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

Langage Java Discussion :

syntaxe des tableaux[]


Sujet :

Langage Java

  1. #1
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut syntaxe des tableaux[]
    bonjour à tous,

    j'ai plusieurs tableaux de composants différents : comp, lampe, interrupteur....

    Quand je veux créer un nouveau composant, je parcours le tableau qui stocke ces derniers, et je prends le premier index ou l'objet est "null", c'est à dire non défini, car cet emplacement est donc libre.
    le code partiel est :

    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
    	public static void clic_sur_recept( int r, int ix, int iy) {
     
    			JOptionPane.showMessageDialog(null, " clic sur recept : " + r + "   on va créer un " + Var.matériel);
    			String toto = "Var." + Var.matériel;
    			JOptionPane.showMessageDialog(null, " toto =  : " + toto);
    				if (Var.matériel== "lampe") {
    						// si une ligne du tableau "comp" est dispo, on l'attribue au prochain composant
    							for (int n=0; n<Const.nb_R; n++) {
     
    									if (Var.comp[n] == null) {
    							//			JOptionPane.showMessageDialog(null, " je vais créer le comp : " + i );
     
    										attribComp(r, ix, iy, n) ;
    										break;
    									}
    							}
    				}
    		}
    A la ligne 10, je cherche un emplacement libre dans le tableau "comp" de la classe Var.
    Cela fonctionne mais je dois répéter ce code pour tous mes tableaux contenant des objets.

    J'ai tenté de créer une chaine "toto" à la ligne 4, contenant le début de la référence au tableau : "Var." en concaténant avec le contenu de la variable "Var.matériel", qui contient le nom du tableau.
    La chaine ainsi obtenue est ok, et c'est : "Var.comp".

    En étant un peu trivial, j'ai tenté de remplacer la ligne 10 par : "if ( toto[n] == null)" ......
    mais cela ne fonctionne pas, car le programme cherche un tableau toto[] et n'interprète pas ce "toto" comme son contenu qui est "Var.comp", qui lui, est un vrai tableau qui fonctionne.

    Ma question est donc : est-il possible d'indiquer le nom d'un tableau sur lequel travailler, non pas directement avant les crochets d'indexation "[]" mais dans une variable dont on peut remplir la valeur avec le nom du tableau à traiter???

    Bravo à ceux qui comprendront la question, déja!!

    Merci à ceux qui tenteront une réponse!!

  2. #2
    Membre expérimenté Avatar de Cincinnatus
    Homme Profil pro
    Développeur d'applications métier
    Inscrit en
    Mars 2007
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur d'applications métier
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2007
    Messages : 592
    Points : 1 679
    Points
    1 679
    Par défaut
    Bonjour,

    A priori il faudrait passer par une Map de List.

    Exemple (avec un bloc-notes) :
    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
      // tableau associatif : clé = type de composant, valeur = liste de composants
      Map<String, List> mapComposants = new HashMap<String,List>();
      
      // on prépare une liste par type de composant
      mapComposants.put("lampe", new ArrayList());
      
      [...] 
      
      List<Object> tableauComposants = (List<Object>)mapComposants.get( typeComposant );
      if (tableauComposants != null) {
        // si une ligne de la liste est dispo, on l'attribue au prochain composant
        int n = 0;
        while ((n<Const.nb_R) && (tableauComposants[n] != null)) {
        attribComp(r, ix, iy, n) ;
        break;
           }
          n++;
      }
    Les différents "tableaux" sont ainsi accessibles par la clé qui définit leur type ("lampe" par exemple) et doivent être remplis par des listes (ArrayList par exemple) contenant les composants.


    Autre chose : la ligne suivante est erronée :
    if(Var.matériel== "lampe")

    Pour les comparaisons de String, il faut utiliser s1.equals(s2), d'une part, pas l'opérateur == qui ne vérifiera pas la valeur mais la référence. Et les initiales majuscules sont réservées aux types de données (comme String ou List), pas aux objets.

  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
    Salut,

    Soit on continue d'utiliser des tableaux et on fait une map de tableaux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    Map<String, Object[]> mapComposants = new HashMap<>();
    mapComposants.put("lampe", new Object[]);
     
      // [...] 
     
      Object[] tableauComposants = mapComposants.get( Var.materiel ); // le cast est inutile)
    Soit on utilise une List, et autant utiliser ses capacités d'ajout/suppression plutôt que de gérer des "emplacements" null. A moins que l'index soit utilisé dans la gestion (au quel cas, on peut utiliser une Map<Integer,...> pour l'accès direct par l'index).
    D'ailleurs, il y a une erreur dans le code de @Cincinnatus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while ((n<Const.nb_R) && (tableauComposants[n] != null)) {
    tableauComposants étant une List, ça devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while ((n<Const.nb_R) && (tableauComposants.get(n) != null)) {


    Une autre approche serait d'utiliser un switch pour affecter la variable intermédiaire :

    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
    Object[] tableauComposants; 
    // on cherche le tableau qu'on veut utiliser en fonction du type de matériel
    switch(var.materiel) {
    case "lampe":
       tableauComposants  = var.lampe;
       break;
    case "comp":
       tableauComposants  = var.comp;
       break;
    case "interrupteur":
       tableauComposants = var.interrupteur;
       break;
    default:
       tableauComposants  = null; 
    }
     
    if( tableauComposants!=null ) { 
        // ... chercher un emplacement libre dans tableauComposants
    }
    }
    Mais l'avantage d'une Map est qu'on peut ajouter des nouveaux types de composants sans avoir à modifier le code (du switch).


    PS: éviter les accents dans les noms (Var.materiel au lieu de Var.matériel)
    PS2: attention à la confusion possible entre une variable de nom "var" et le "type" var.
    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 expérimenté Avatar de Cincinnatus
    Homme Profil pro
    Développeur d'applications métier
    Inscrit en
    Mars 2007
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur d'applications métier
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2007
    Messages : 592
    Points : 1 679
    Points
    1 679
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    D'ailleurs, il y a une erreur dans le code de @Cincinnatus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while ((n<Const.nb_R) && (tableauComposants[n] != null)) {
    tableauComposants étant une List, ça devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while ((n<Const.nb_R) && (tableauComposants.get(n) != null)) {
    Exact, mea culpa ! J'ai voulu adapter depuis un tableau et sans compiler, donc sans filet...

  5. #5
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut merci à Cincinnatus et joel.drigo
    Merci pour votre réactivité et vos précieuses pistes que je vais tenter d'exploiter au mieux...

    En effet, l'indexation des objets est utile car je m'en sers pour ensuite gérer ces objets au fil de l'exécution du programme.

    A bientôt peut-être pour d'autres problématiques, car je manque encore de connaissances solides....

  6. #6
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut quelques précisions à venir....
    j'ai réalisé un petit test pour essayer les Maps.

    J'ai trois tableaux (les listes me gènent car je travaille avec l'indexation pour retrouver mes objets ensuite...)

    j'ai deux types différents : Strings et Color.

    Je mets mes trois tableaux dans la map, puis je récupére le tableau de "Color" dans le tableau de type "Object" nommé "test", puis j'ajoute la couleur jaune à l'index libre (le 2).
    A la fin j'affiche le conenu de "test" et de "color".

    Le code est :

    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
    import java.awt.Color;
    import java.util.HashMap;
    import java.util.Map;
     
    public class Main {
     
    	public static void main(String[] args) {
     
    		Color[] color = new Color[10];
    		String couleur[] = new String[10];
    		String [] nombre = new String[10]	;
     
     
    		// tableau "couleur" de type String
    		couleur[0] = "noir";
    		couleur[1] = "marron";
    		couleur[2] = "rouge";
    		couleur[3] = "bleu";
    		couleur[4] = "vert";
     
    		// tableau "nombre" de type String
    		nombre[0] = "zéro";
    		nombre[1] = "un";
    		nombre[2] = "deux";	
     
    		// tableau "color de type Color
    		color[0] = Color.black;
    		color[1] = Color.white;
     
     
    		// ma map de tableaux de STrings
    		// 1,2,3 : clé d'accès à la valeur	||  couleur, nombre, color : valeur choisie (ici, c'est un tableau)
    		Map <String,  Object[]> ma_map = new HashMap();
    		ma_map.put("1", couleur);
    		ma_map.put("2", nombre);
    		ma_map.put("3", color);
     
    		// ma récupération du tableau de la map dans un tableau de test
    		Object[] test = new Object[10];
    		test = ma_map.get("3");
     
    		// chercher une place libre pour mettre le "jaune" à l'index 2.
    		for (int i=0; i<test.length; i++) {
    			if (test[i]==null) {
    				test[i] = Color.yellow;
    				System.out.println("j'ai bien mis le jaune à l'index 2.");
    				break;
    			}
    		}
     
     
    		// affichage du contenu du tableau récupéré
    		int i = 0;
    		while (test[i] != null) {
    			System.out.println("test[" + i + "] = " + test[i] + "             et color[" + i + "] = " + color[i]);
    			i++;
    		}
     
     
    	}
    }


    le résultat est le suivant :

    j'ai bien mis le jaune à l'index 2.
    test[0] = java.awt.Color[r=0,g=0,b=0] et color[0] = java.awt.Color[r=0,g=0,b=0]
    test[1] = java.awt.Color[r=255,g=255,b=255] et color[1] = java.awt.Color[r=255,g=255,b=255]
    test[2] = java.awt.Color[r=255,g=255,b=0] et color[2] = java.awt.Color[r=255,g=255,b=0].

    Cela semble fonctionner mais deux questions me gênent pourtant :

    1/ A la ligne 40, je mets le tableau de "Color" de la map, dans mon tableau de test de type "Object".
    Les deux types des tableaux ne sont donc pas rigoureusement identiques.
    Comment se fait-il que je puisse, à la ligne 45, affecter "Color.Yellow" dans le tableau test qui est "Object" et non "Color" sans devoir faire un "cast"??

    2/ A l'index 2 du tableau "test", j'ai mis la couleur jaune. A l'affichage, cette couleur apparait bien dans le "test[2], mais également dans le color[2], sans que je sois intervenu...
    Cela m'arrange plutôt, car c'est le but pour moi, mais cet mise à jour des tableaux initiaux est-elle tout le temps automatique?...

    Merci à ceux qui se pencheront sur mes interrogations....

  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 patdu26 Voir le message
    1/ A la ligne 40, je mets le tableau de "Color" de la map, dans mon tableau de test de type "Object".
    Les deux types des tableaux ne sont donc pas rigoureusement identiques.
    Comment se fait-il que je puisse, à la ligne 45, affecter "Color.Yellow" dans le tableau test qui est "Object" et non "Color" sans devoir faire un "cast"??
    Parce que la classe java.awt.Color étend (indirectement) la classe Object (comme toutes les classes d'ailleurs).

    • On doit caster lorsqu'on doit affecter à une variable a la valeur d'une variable b tel que le type de a n'est pas une généralisation du type de b (mais que la valeur l'est bien en revanche).
      La généralisation c'est quand on monte dans l'héritage (Object est une généralisation de toute les classes, Number est une généralisation de Integer, Double, Float, etc.
      La spécialisation c'est quand on descend : Integer est une spécialisation du type Number qui est lui-même une spécialisation du type Object.
    • Si on doit caster, on peut caster vers n'importe quel type spécifique du type de a qui soit un généralisation du type de la valeur.
    • En revanche, inutile de caster lorsque le type de a est une généralisation du type de b, le cast est implicite.
    • Le cast est là pour dire au compilateur "oui je sais que la variable n'est pas d'un type compatible (pas le même, ou pas un descendant), mais fait moi confiance, je sais que la valeur dedans est du type qu'on veut
    • Si tu veux un moyen simple au début pour savoir quand caster ou pas : ne caste pas, si ça compile pas, alors c'est qu'il faut caster pour que ça compile (ce qui ne veut pas dire que si tu le fais ça fonctionnera à l'exécution)


    Concrètement :
    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
    public static void main(String[] args) {
     
    		Integer i = 42; // n est du type Integer et 42 est du type Integer
    		Number n = 2021; // n est du type Number et 2021 du type Integer : Number étant une généralisation de Integer, alors pas de problème d'affectation et cast inutile 
     
    		Number cn = i; // cn est du type Number et i du type Integer : Number étant une généralisation de Integer, alors pas de problème d'affectation et cast inutile 
     
    		Object x = i; // x est du type Object et i du type Integer : Object étant une généralisation de Integer, alors pas de problème d'affectation est cast inutile
     
    		Integer si = (Integer)x; // x contient bien un Integer, mais le type de si (Integer), n'est pas une généralisation du type de x (Object), donc il faut caster
     
    		Number sn = (Integer)x; // x contient bien un Integer, mais le type de sn (Number), n'est pas une généralisation du type de x (Object), donc il faut caster
     
    		Integer ok = (Integer)n; // n contient bien un Integer, même s'il est du type Number, mais le type de ok (Integer), n'est pas une généralisation du type de n (Number), donc il faut caster
     
    		n = 1.5d; // je mets un Double dans n (cast inutile)
     
    		// Integer err = (Integer)n; // n contient un Double, mais le type de err (Integer), n'est pas une généralisation du type de n (Number), donc il faut caster pour compiler, mais ça plantera à l'exécution
                     // ici, si tu décommentes la ligne juste avant, tu auras une exception java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Integer
    	}

    Avec ta Map <String, Object[]> ma_map = new HashMap();, tu n'auras pas de souci de cast lors de l'affectation dans un tableau. En revanche, si tu veux récupérer une instance du tableau de java.awt.Color, tu seras obligé de caster.

    Soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Color[] tableau = (Color[])ma_map.get("3");
    Color col = tableau[1];
    Soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] tableau = ma_map.get("3");
    Color color = (Color)tableau[1];


    Citation Envoyé par patdu26 Voir le message
    2/ A l'index 2 du tableau "test", j'ai mis la couleur jaune. A l'affichage, cette couleur apparait bien dans le "test[2], mais également dans le color[2], sans que je sois intervenu...
    Cela m'arrange plutôt, car c'est le but pour moi, mais cet mise à jour des tableaux initiaux est-elle tout le temps automatique?...
    Les variables de type objet, ou tableau, (attention pas les variables de type primitif) en Java contiennent toujours des références (une sorte d'adresse de l'objet en mémoire). C'est la syntaxe Java qui donne l'impression qu'on manipule une valeur qui est celle de l'objet ou du tableau. Mais on manipule un objet et la variable sert à en connaître la référence en mémoire.

    Les variables servent à manipuler les données dans le code, mais au final ce sont les références des objets qui comptent : c'est la référence de l'objet qui détermine quel objet sera manipulé. Si deux variables différentes ont pour valeur la même référence du même objet, la manipulation de l'objet par une variable est forcément reflété par l'autre parce que c'est le même objet. Il n'y a pas de copie, de tableaux initiaux, etc...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int[] tab1 = {1,2,3};
    int[] tab2 = tab1;
    tab1 et tab2 sont deux variables différentes dont la valeur est la référence du même tableau unique.

    Donc si tu fais tab2[1]=42;, tu modifies la cellule d'index 1 du tableau référencé par tab2, qui également celui référencé par tab1, donc System.out.println(tab1[1]); affiche 42.

    Attention, c'est bien le tableau qui est modifié, pas une sorte de valeur de tab2 ou tab1 qui serait un tableau, puisque la valeur de ces variables, c'est une référence de tableau.

    Si tu fais après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab2 = new int[]{5,6,7};
    tu changes la valeur de tab2, on y mettant la référence d'un nouveau tableau qui contient 5, 6, 7. Le tableau référencé par tab1 n'est pas concerné, c'est un autre tableau, il ne change donc pas. La variable tab1 n'est pas concernée par cette affectation donc sa valeur ne change pas : c'est toujours la référence du le premier tableau. Du coup, maintenant tab2[1]=2021; ne modifiera pas le tableau référencé par tab1 forcément.
    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 habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut Merci!
    Merci joel de me faire profiter de tes connaissances en java. Les précisions sont très claires, avec des exemples de codes dans chaque cas. Nickel!:applo

    Cela me permet de prendre du recul sur mon code et de progresser plus rapidement.

    A bientôt peut-être pour d'autres incertitudes....

  9. #9
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut Map avec Classe perso qui étend JComponent
    Bonjour à tous, malgré vos précieux conseils, une nouvelle interrogation apparait néanmoins....

    Je reste sur l'utilisation des "maps", pour essayer d'appliquer des méthodes identiques à des tableaux contenant des objets différents.

    Hier, on m'a expliqué, que la classe "Object" est la mère et tous les types d'objets. L'utilisation de "map" fonctionne très bien avec les objets "natifs" du langage : Strings, Color...), notamment pour créer de nouveaux objets, sans devoir rappeler le nom de la classe (Color col = tableau[1])

    Or, dans mon cas, je travaille avec des composants personnels, créés dans une classe qui étend JComponent. J'ai fait un petit code qui, crée une classe "ObjetsPerso", qui étend "JComponent".
    Je créé 5 objets sur les indices de 0 à 4, avec des propriétés natives (name, taille) et perso (dureré, indice).

    le code est :

    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
    import java.awt.Color;
    import java.util.HashMap;
    import java.util.Map;
     
    import javax.swing.JComponent;
     
    public class Main {
     
    	public static void main(String[] args) {
     
    		// Classe personnelle qui étend JComponent
    			class ObjetsPerso extends JComponent {
     
    				int dureté = 0;
    				int indice = 0;
     
    				public ObjetsPerso (int i, int dureté) {
    					this.dureté = dureté;
    					this.setSize(20, 20);
    					this.setName("mon_objet"+i);
    					this.indice = i;
    				}
    			}
     
    		// Mes tableaux de variables			
    		Color[] color = new Color[10];
    		String[] couleur = new String[10];
    		String [] nombre = new String[10]	;
    		ObjetsPerso[] mesobjets = new ObjetsPerso[10];
     
     
    		// tableau "couleur" de type String
    		couleur[0] = "noir";
    		couleur[1] = "marron";
    		couleur[2] = "rouge";
    		couleur[3] = "bleu";
    		couleur[4] = "vert";
     
    		// tableau "nombre" de type String
    		nombre[0] = "zéro";
    		nombre[1] = "un";
    		nombre[2] = "deux";	
     
    		// tableau "color de type Color
    		color[0] = Color.black;
    		color[1] = Color.white;
     
    		// tableau "mesobjets"
    		for (int i=0; i<5; i++) {
    			mesobjets[i] = new ObjetsPerso (i, 2*i);
    		}
     
    		// ma map de tableaux de STrings
    		// 1,2,3 : clé d'accès à la valeur	||  couleur, nombre, color, mesobjets : valeur choisie (ici, c'est un tableau)
    		Map <String,  Object[]> ma_map = new HashMap();
    		ma_map.put("1", couleur);
    		ma_map.put("2", nombre);
    		ma_map.put("3", color);
    		ma_map.put("4", mesobjets);
     
    		// ma variable "test" contient à présent la même référence que la variable "mesobjets".
    		// les deux variables pointent la même zone mémoire et modifie les mêmes variables.
    		Object[] test = new Object[10];
    		test = ma_map.get("4");
     
    		// chercher une place libre dans ce tableau
    		for (int i=0; i<test.length; i++) {
    			if (test[i] != null) {
    				System.out.println("mesobjets[" + i + "] = " + test[i]);
    			}
    			else {System.out.println("l'index n° " + i + " est libre.");
    				mesobjets[i] = new ObjetsPerso (i,2*i);
    		//		test[i] = new test(i,2*i);
    				break;
    			}
     
    		}
    	}
     
    }
    J'utilise la map pour récupérer la référence de ce tableau dans la variable test, et j'affiche correctement.

    Si je créé un nouveau composant perso à la suite, en précisant la classe (ligne 72), en rappelant le nom de la classe désirée, ça fonctionne très bien, rien à dire.

    Cependant, que je choisis un objet de ma table, la classe sera différente à chaque fois.
    Si je désire créer un nouveau composant, sans préciser la classe (ligne 73), puisque je travaille à présent sur "test" , cela ne fonctionne pas, car le compilateur me dit que la classe "test" n'est pas définie ce qui est vrai...
    Il ne semble pas naturellement faire le lien entre l'objet tableau récupéré par "test" et la classe des objets contenus dans le tableau......

    Question :
    Quand je crée ma variable "test" qui récupère la référence vers "mesobjets" (ligne 59) via la clé "4" de la map, la classe de "mesobjets" n'est-elle pas automatiquement récupérée et liée à l'objet "test"?

    L'intérêt à mes yeux de cette map est d'utiliser ensuite la même méthode pour construire mes objets, quel que soit cet objet, de type "classe JComponenet étendu".
    Si je dois rappeler la classe requise pour créer l'objet, l'intérêt de cette "map" m'échappe pour les objets perso, non natifs du langage...
    Cela est-il donc possible?

    Merci à tous ceux qui se pencheront sur la compréhension de ma question, et à ceux qui répondront peut-être....

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hello,

    c'est juste qu'un tableau ne suffit pas. Un tableau sert à stocker des objets et à les retrouver, pas à créer de nouveaux objets.

    Pour un truc comme celui que tu décris, un tableau ne suffira pas. Il va falloir que tu définisses un genre de "manager d'objets" pour chaque genre d'objets que tu veux pouvoir gérer, et que ce soit ça que tu mettes dans ta Map.

    Un Manager d'objet, contiendra d'une part un tableau des objets en question (encore que sérieusement, arrête les tableaux et utilise des ArrayList. Vraiment.) et d'autre part un objet qui peut créer de nouveaux objets. En conception, on appelle ça une fabrique, ou factory en anglais.

    Ainsi donc, quand tu voudras créer de nouveaux objets d'un type précis, tu pourras récupérer son manager, et demander à ce manager de créer un nouvel objet.

    Ça peut ressembler à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Manager manager = maMap.get("4");
    Object nouvelObjet = manager.newObject(i, 2*i);
    Le problème auquel tu vas être confronté, c'est les paramètres à passer à la construction d'un objet.

    Dans ton exemple il y a deux paramètres : i et 2*i, du coup j'ai fait un exemple qui fait pareil.
    Mais est-ce que tous les genres d'objets vont toujours prendre les mêmes paramètres ?

    Parce que si ce n'est pas le cas, tu devrais te rendre compte que depuis le départ tu cours après une illusion : si tes objets ont besoin de paramètres différents, tu vas devoir les gérer tous chacun à sa manière, il n'y a évidemment pas le choix.
    C'est d'ailleurs à ça que ça sert, qu'ils aient des paramètres différents : à s'assurer qu'ils soient gérés chacun à sa manière et surtout pas tous rassemblés pareil.
    Si tu leurs donnes des paramètres différents, c'est uniquement dans le but que tout ce dont tu parles depuis le début soit impossible. Ça ne sert à rien à d'autre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut bonjour thevin
    bonjour thelvin, merci pour ton message.

    En fait, j'ai réalisé une interface avec cases de positionnement de couleur, à la manière d'un damier, qui me permet, au clic, de positionner cet composant perso sur ce damier.

    En effet, les types de composants ont un constructeur spécifique à chaque fois (apparences, propriétés et méthodes contenues dans chaque constructeur dédié.)

    Je cherchais à ne pas reproduire le même code, puisque c'est déconseillé en informatique, et que la démarche est identique pour chaque composant :
    - chercher le tableau stockant le type de composant perso choisi.
    - Trouver une place dans le tableau en le parcourant. (des places peuvent apparaitre dans le désordre car des composants dans les index bas ont pu être créés, puis supprimés pendant l'utilisation de l'application)
    - créer un composant nouveau de ce type au premier emplacement libre et le positionner sur la case.

    En fait, je pensais pouvoir créer une méthode générique, quel que soit le type de composant choisi, ce type étant un peu un paramètre de la méthode..
    La problématique est d'une part que :

    -pour accéder à un tableau, je n'ai pas pu "leurrer" le compilateur, en utilisant une variable qui contiendrais le nom du tableau à traiter dans le genre :
    String montableau = "interrupteur", puis ensuite tenter : montableau[]...... car le compilateur veut travailler avec un tableau dont le nom serait "montableau"....
    En passant par la Map, cette problématique semblait résolue.

    Cependant, quand je récupère dans la Map, le tableau choisi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] test = new Object[10];
    test = ma_map.get("4");
    En fait j'accède à mes objets du tableau choisi via la clé 4, mais la problématique ressurgit à la création d'un nouvel objet, car la classe n'est pas directement connue et donc, le "new" est impossible, puisque le constructeur n'est pas accessible...

    Tu as raison, c'est peut-être un peu utopique.
    Je vais revenir à une approche plus simple, avec un "switch" au moment du choix, qui m'emmènera vers autant de méthodes que de choix possibles.
    Ces méthodes seront assez proches dans le construction puisque le changement principal sera la classe choisie pour le traitement.
    La contrainte est que chaque nouveau composant imposera une nouvelle extension d'un morceau de code presque identique..

    Encore merci à tous pour vos remarques, vos conseils et vos morceaux de codes très formatifs.

    Même quand on dérive un peu et que le chemin choisi n'aboutit pas forcement, on apprend toujours!!...... (ok, je vais voir de près les ArrayList!)

  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
    Plutôt que des switches, si les fonctionnalités se multiplient, privilégie une approche objet : tu regroupes les différentes fonctionnalités de gestion d'un type de composant dans une classe paramétrée. Tu limiteras ainsi la duplication de code.

    Par exemple :
    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
    public abstract class GestionnaireComposant<T extends JComponent> { // le paramètre T étend le type commun des classes de composants que tu gères
     
            private Object[] emplacements = new Object[10];
     
            public boolean emplacementLibreExiste() {
                    return emplacementLibre()==-1;
            }
     
    	public int emplacementLibre() {
    		for(int i=0; i<emplacements.length; i++) {
    			if ( emplacements[i]==null ) return i;
    		}
    		return -1; // pas d'emplacement libre
    	}
     
    	public int ajouteNouveauComposant() {
                    int emplacement = emplacementLibre();
                    if ( emplacement>=0 ) {
    		      emplacements[emplacement] = creerComposant(emplacement,2*emplacement);
                    }
                    return emplacement;
    	}
     
    	public T getComposant(int emplacement) {
    		return (T)emplacements[emplacement];
    	}
     
            // à implémenter dans la classe spéficique pour créer l'instance de composant spécifique
    	public abstract T creerComposant(int x, int y);
     
    }
    Tu peux ensuite ajouter les méthodes dont tu as besoin, celles qui sont communes à chaque type de composant.

    Tu implémentes ensuite pour chaque type une classe spécifique, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class GestionnaireComposantLampe extends GestionnaireComposant<Lampe> {
        public Lampe creerComposant(int x, int y) {
               return new Lampe(x,y);
        }
    }
    Le code de l'implémentation spécifique se limite à ce qui est spécifique à chaque composant.

    Dans la map tu stockes chaque type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Map<String, GestionnaireComposant<?>> map = new HashMap<>();
    map.put( "lampe", new GestionnaireComposantLampe()) ;
    map.put( "interrupteur", new GestionnaireComposantInterrupteur());
    Ensuite, il suffira d'utiliser le gestionnaire en fonction du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    String type = "lampe";
     
    // ...
     
    GestionnaireComposant<?> gestionnaireComposant = map.get(type);
    int emplacement = gestionnaireComposant.ajouteNouveauComposant();
    if( emplacement<0 ) {
        System.out.println("Il n'y avait pas d'emplacement libre");
    }
    else {
        System.out.println("Un composant " + type + " a été ajouté à l'emplacement " + emplacement);
        JComponent jcomponent = gestionnaireComposant.getComposant(emplacement);
        // faire ce que tu veux ici avec le composant...
    }
    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 habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut merci Joel.drigo
    bonjour Joël,

    tu as très bien analysé ma problématique et ta structure me semble correspondre tout à fait à mes besoins :
    - à la fois une partie de classe "commune" à tous mes objets perso, et une partie "spécifique" pour chacun, contenant au minimum le constructeur.

    Tout cela semble ficelé de manière concise et efficace, Bravo pour cette structure que je comprends peu à peu, mais que je n'aurais pas su imaginer.

    Je vais tenter d’adapter ce modèle et je mettrais un message pour dire si cela fonctionne.

    Encore merci pour le temps passé et les idées!!

  14. #14
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut Merci joel.drigo, ca fonctionne!!
    Juste un petit mot pour dire que la classe abstraite paramétrée fonctionne très bien!

    La map récupère bien un gestionnaire spécifique directement lié au type de mon composant.
    Le gestionnaire commun permet d'effectuer des routines d'attribution communes à tous mes objets et les méthodes qui utilisent les spécificités restent abstraites ici.

    Chaque gestionnaire spécifique étend le gestionnaire commun et précise pour chaque type, les fonctions propres, relatives aux constructeurs et aux tableaux d'affectation.

    Encore merci!!!

    Je joins un aperçu de mon interface en construction :

    Nom : mon_interface.png
Affichages : 312
Taille : 11,9 Ko

    A bientôt pour d'autres difficultés...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Est ce que ce syntaxe est juste ?( a propos des tableaux)
    Par lahdili.reda dans le forum Langage
    Réponses: 7
    Dernier message: 20/06/2012, 13h56
  2. Réponses: 101
    Dernier message: 20/09/2010, 10h20
  3. Réponses: 39
    Dernier message: 11/08/2010, 09h28
  4. [Tableaux] syntaxe des guillemets
    Par tioseb dans le forum Langage
    Réponses: 13
    Dernier message: 31/01/2006, 14h35
  5. free sur des tableaux "a moitié dynamiques"
    Par barthelv dans le forum C
    Réponses: 4
    Dernier message: 31/07/2003, 15h30

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