Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Java] Récupérer un composant grâce à son nom

Sujet résolu
    31 octobre 2014 à 1:18:18

    Bonjour, je souhaite récupérer des objets hérités de Component grâce à leur nom.

    Pour vous expliquer le problème je dispose d'un ensemble de classes s'occupant de générer un formulaire, à la manière du cours de PHP Orienté Objet, j'ai donc :

    - Une classe Form représentant le formulaire contenant des objets héritant d'une classe perso Field.

    - Un objet héritant de Field définis par un nom, un label, une valeur, des validateurs et un composant (un JTextField par exemple).

    Ce que je souhaiterai faire, c'est récupérer ce qu'à saisis l'utilisateur pour remplir le formulaire, à savoir le contenu des JTextField.

    Sachant que lorsque je les initialise pour les afficher dans la fenêtre j'utilise la méthode setName() héritée de la classe Component, je souhaiterai savoir s'il est possible de récupérer la valeur du JTextField en l'identifiant par son nom.

    Je ne sais pas si mes explications sont claires mais j'attends vos réponses avec impatience ;)

    Pour l'idée, voici à quoi ressemble ma classe qui s'occupe de ça, j'ai rajouté des commentaires :

    public class CreerUnClient extends JPanel implements ActionListener  {
    
    	private Form form;
    	
    	public CreerUnClient(){
    		super();
    		
    		/* 1. Le système affiche un message de création de client */
    		ClientFormBuilder builder = new ClientFormBuilder(new Client()); // Constructeur de formulaire
    		this.setForm(builder.getForm()); // Une fois le formulaire créé on l'assigne à l'objet
    		JButton valider = new JButton("Valider");
    		valider.addActionListener(this);
    		
    		JPanel panneau = new JPanel();
    		panneau.add(this.getForm().createView()); // createView() génère un JPanel contenant le formulaire
    		panneau.add(valider);
    		this.setLayout(new BorderLayout());
    		this.add(panneau, BorderLayout.CENTER);
    	}
    	
    	/* 2. L'utilisateur saisis les informations */
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		/* Attributions des valeurs à chaque objet Field */
    		/* ?? */
    		/* 3. Le système vérifie que les saisies sont valides */ // J'utiliserai les validateurs de Field
    
    		
    		/* 4. L'utilisateur confirme la création d'un client */ // Un simple JOptionPane + communication avec la bdd
    		
    	}
    	
    	public void setForm(Form form){
    		this.form = form;
    	}
    	
    	public Form getForm(){
    		return this.form;
    	}
    
    }



    • Partager sur Facebook
    • Partager sur Twitter
      31 octobre 2014 à 11:49:14

      Deux solutions s'offrent à toi. Soit tu as une utilisation fréquente des noms, et il est plus efficace de tout stocker dans une Map, soit tu parcours tous les composants de ton JPanel et tu prends celui qui a le bon nom.

      Pour la première solution :

      public class Clazz{//Soit une classe quelconque
      
          private JPanel panel = new JPanel();//Ton JPanel
          private Map<String, Component> components = new HashMap<String, Component>();
      
          public void ajouterComposant(Component comp){
              this.panel.add(comp);
              this.components.put(comp.getName(), comp);
          }
      
          public Component getComposant(String nom){
              return this.components.get(nom);
          }
      }

      (Je trouve cette méthode un peu "surcouche" mais elle s'avèrera plus performante si tu utilise sans cesse la méthode getComponent()).

      Pour la deuxième méthode :

      //Cette méthode renverra ton composant, ou null s'il n'existe pas.
      private void getComponent(JPanel panel, String name){
          for(Component i : panel.getComponents()){
              if(i.getName().equals(name){
                  return i;
              }
          }
          return null;
      }

      Voili voilou :)

      • Partager sur Facebook
      • Partager sur Twitter
      Error 2006, MySQL server has gone away
        31 octobre 2014 à 15:52:42

        Merci beaucoup ! :D

        Je pense que je vais utiliser ta première solution qui m'a l'air d'être en effet plus performante que la seconde qui effectue 1+2+...+n comparaisons d'ici la fin de la boucle !

        Je te remercie infiniment ! Je mets en résolu quand j'aurai réussi à l'implémenter dans mon programme :)

        • Partager sur Facebook
        • Partager sur Twitter
          31 octobre 2014 à 17:31:40

          Non attention : la boucle s'arrête dés la première occurrence car l'instruction "return" marque la fin de la fonction.

          Considérons la liste de chaînes de caractères List<String> ayant pour valeurs : chocolat, lait, bière, café, jus (Faut peut être que j'aille boire moi... ^^).

          Si on exécute la boucle pour le nom "lait", voici ce que la boucle scannera :

          chocolat, lait (Fin de la boucle, l'objet a été trouvé).

          jimdeplouz a écrit:

          Je te remercie infiniment ! Je mets en résolu quand j'aurai réussi à l'implémenter dans mon programme :)

          Pas de problème !

          -
          Edité par EclipseOnFire 31 octobre 2014 à 17:33:47

          • Partager sur Facebook
          • Partager sur Twitter
          Error 2006, MySQL server has gone away
            1 novembre 2014 à 1:48:21

            EclipseOnFire a écrit:

            Non attention : la boucle s'arrête dés la première occurrence car l'instruction "return" marque la fin de la fonction.

            Considérons la liste de chaînes de caractères List<String> ayant pour valeurs : chocolat, lait, bière, café, jus (Faut peut être que j'aille boire moi... ^^).

            Si on exécute la boucle pour le nom "lait", voici ce que la boucle scannera :

            chocolat, lait (Fin de la boucle, l'objet a été trouvé).

            En effet, cependant comme je vais devoir appeler cette fonction pour chaque élément de mon formulaire à sa validation, en reprenant ton exemple :
            • 1 : retourne chocolat,
            • 2 : chocolat, retourne lait,
            • 3 : chocolat, lait, retourne bière,
            • 4 : chocolat, lait, bière, retourne café,
            • 5 : ...
            Alors qu'avec la Map, je la parcours une seule fois car je sais ce que je doit récupérer, je trouve cela plus efficace :)


            • Partager sur Facebook
            • Partager sur Twitter
              1 novembre 2014 à 2:04:09

              Je n'ai pas le temps de tester le code ce soir mais du coup à l'aide de ta première solution j'ai implémenté deux méthodes dans ma class Form :

              public Field getField(String name){
              	for(Field field : this.getFields()){
              		if(field.getName().equals(name)){
              			return field;
              		}
              	}
              	return null;
              }
              	
              public Component getComponent(String nom){
              	return this.map.get(nom);
              }

              Et du coup dans ma classe qui affiche le formulaire et le traite :

              public void actionPerformed(ActionEvent e) {
              		/* Attributions des valeurs à chaque objet Field */
              		Iterator it = this.getForm().getMap().keySet().iterator();
              		while (it.hasNext()){
              		   String nom = (String) it.next(); // Récupère le nom du composant
              		   JTextField comp = (JTextField) this.getForm().getComponent(nom); // Récupère son composant
              		   this.getForm().getField(nom).setValue(comp.getText());
              		} /* Etc... */

              Je ne sais pas si c'est une bonne manière de faire, pour être honnête c'est la première fois que j'utilise une Map ^^

              • Partager sur Facebook
              • Partager sur Twitter
                1 novembre 2014 à 12:07:17

                Ça marchera, mais tu t'es grandement compliqué la vie ;).

                //La map retournée par la méthode "getMap()" devra être de type Map<JTextField, Field>.
                public Field getField(String name){
                    for(Field i : this.getForm().getMap().values()){
                        if(i.getName().equals(name)){
                            return i;
                        }
                    }
                    return null;
                }
                
                public void actionPerformed(ActionEvent e){
                    for(JTextField i : this.getForm().getMap().keySet()){
                        Field field = this.getForm().getMap().get(i);
                        field.setValue(i.getText());
                        //Etc...
                    }
                }

                Un object Map prend deux paramètres. Le premier correspond à une clé, l'autre à une valeur. Cet objet associe à une clé une valeur. On utilise communément des String comme type de clé, ou encore des Long pour disposer d'un ID. Malgré cela, on peut utiliser les types d'objets que l'on veut.

                Map<?, ?> est une interface. Elle dispose de plusieurs implémentations telles que HashMap, HashTable etc... En français : table de hachage.

                Afin d'ajouter un élément, on utilise la méthode "put(Object key, Object value)", on peut itérer sur les clés ou sur les valeurs, ou encore obtenir une valeur à partir de sa clé "get(Object key)".

                • Partager sur Facebook
                • Partager sur Twitter
                Error 2006, MySQL server has gone away
                  3 novembre 2014 à 13:21:25

                  Ah oui exact je me prends trop la tête :lol:

                  Ça marche parfaitement je te remercie infiniment ! :)

                  • Partager sur Facebook
                  • Partager sur Twitter
                    4 novembre 2014 à 19:04:55

                    Pas de problème !
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Error 2006, MySQL server has gone away

                    [Java] Récupérer un composant grâce à son nom

                    × 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