Utiliser getClass() dans une fonction

Utiliser getClass() dans une fonction - Java - Programmation

Marsh Posté le 10-10-2014 à 16:35:22    

Bonjour,
 
J'ai une classe java qui comprends plusieurs classes (celles-ci implementent ActionListener et utilisent la méthode actionPerformed afin de définir des actions liées à des boutons radio).
Dans chacunes de ces classes, je dois utiliser getClass().getName() puis faire des traitements sur le String obtenu ; et puisque j'ai environ 30 classes, je pensais à créer une fonction qui comprend la recupération du nom de la classe et le traitement afin de réutiliser celle-ci dans toutes les classes en question. Mais celà ne fonctionne pas...
 
Exemple :
Au lieu de :
class Toto1Listener implements ActionListener{
   public void actionPerformed(ActionEvent e){
      String s = getClass().getName();
      s = substring(10,s.length()-2);
      [...etc]
   }
}
 
class Toto2Listener implements ActionListener{
   public void actionPerformed(ActionEvent e){
      String s = getClass().getName();
      s = substring(10,s.length()-2);
      [...etc]
   }
}
 
Faire :
pubic void maFonction(){
   String s = getClass().getName();
   s = substring(10,s.length()-2);
   [...etc]
}
 
class Toto1Listener implements ActionListener{
   public void actionPerformed(ActionEvent e){
      maFonction();
   }
}
 
class Toto2Listener implements ActionListener{
   public void actionPerformed(ActionEvent e){
      maFonction();
   }
}
 
Merci d'avance de votre aide :D

Reply

Marsh Posté le 10-10-2014 à 16:35:22   

Reply

Marsh Posté le 11-10-2014 à 00:56:12    

Il faut faire une methode statique pour ça et lui passer les infos utiles.
 
Tu peux soit le faire en appel local à la fonction, soit faire le calcul de manière unique (static final)
 
Exemples :

Code :
  1. public class Utils{
  2.       public static String getFormattedClassNameFromClass(Class src){
  3.             String s = src.getClass().getName();
  4.               s = ...
  5.               ...
  6.               return s
  7.       }
  8.       public static String getFormattedClassNameFromObj(Object src){
  9.               return getFormattedClassNameFromClass(src.getClass());
  10.        }
  11. }
  12. class Toto1Listener implements ActionListener{
  13.         public void actionPerformed(ActionEvent e){
  14.            String res = Utils.getFormattedClassNameFromObj(this); //Appel local
  15.            ...
  16.         }
  17. }
  18. class Toto2Listener implements ActionListener{
  19.         private static final String CLASSNAME=Utils.getFormattedClassNameFromClass(Toto2Listener.class); //calcul global fait une seule fois
  20.          public void actionPerformed(ActionEvent e){
  21.              //utilisation directe de CLASSNAME
  22.            ...
  23.         }
  24. }


Message édité par dreameddeath le 11-10-2014 à 00:57:35
Reply

Marsh Posté le 14-10-2014 à 16:20:19    

Merci !
 
Autre question qui rejoint le même sujet :
 
Actuellement, j'ai un tableau avec des boutons radios : JRadioButton[] boutons.
Pour leurs ajouter une action, je fais comme cela :
 
boutons[0].addActionListener(new OuvrirConnexion1Listener());
boutons[1].addActionListener(new FermerConnexion1Listener());
boutons[2].addActionListener(new OuvrirConnexion2Listener());
boutons[3].addActionListener(new FermerConnexion2Listener());
 
puis :
 
class OuvrirConnexion1Listener implements ActionListener{
        public void actionPerformed(ActionEvent e){
                 [[actions a effectuer]]
        }
}
 
class FermerConnexion1Listener implements ActionListener{
        public void actionPerformed(ActionEvent e){
                 [[actions a effectuer]]
        }
}
 
class OuvrirConnexion2Listener implements ActionListener{
        public void actionPerformed(ActionEvent e){
                 [[actions a effectuer]]
        }
}
 
class FermerConnexion2Listener implements ActionListener{
        public void actionPerformed(ActionEvent e){
                 [[actions a effectuer]]
        }
}
 
 
Le problème c'est que j'ai 28 boutons (et cela peut encore augmenter) ; donc y a-t-il un moyen de factoriser ce genre de code (via une boucle...autres...) ??!

Reply

Marsh Posté le 16-10-2014 à 15:25:37    

ça dépend : que veux-tu changer en fonction du bouton
 
Tu peux imaginer

Code :
  1. class ActionConnexionListener implements ActionListener{
  2.         private Connection m_connection;
  3.         private ConnectionAction m_action;
  4.         public ActionConnexionListener(Connection connection,ConnectionAction action){
  5.              m_action = action;
  6.              m_connection = connection
  7.         }
  8.         public void actionPerformed(ActionEvent e){
  9.                 switch(m_action){
  10.                      case OPEN: m_connection.open();
  11.                      case CLOSE: m_connection.close();
  12.                 }
  13.         }
  14.         public enum ConnectionAction {
  15.             OPEN,
  16.             CLOSE
  17.         }
  18. }


 
Et tu peux initialiser :

Code :
  1. for(int i=0;i<...:i+=2){
  2.     button[i].addActionListener(new ActionConnexionListener(connections[i],ConnectionAction.OPEN);
  3.     button[i+1].addActionListener(new ActionConnexionListener(connections[i],ConnectionAction.CLOSE);
  4. }


 
A adapter au cas par cas...


Message édité par dreameddeath le 16-10-2014 à 15:25:58
Reply

Marsh Posté le 17-10-2014 à 10:29:11    

En fait, j'ai actuellement une methode commande(int n) qui contient un switch d'actions à effectuer en fonction de n (sur un objet GestionAccesFirewall qui contient les méthodes d'ouverture/fermeture/actualisation de différentes connexions) :
 

Code :
  1. GestionAccesFirewall firewall = new GestionAccesFirewall();
  2. public void commande(int n){
  3.    switch(n){
  4.    case 1:
  5.       firewall.ouvrirTOTO();
  6.       break;
  7.    case 2:
  8.       firewall.fermerTOTO();
  9.       break;
  10.    case 3:
  11.       firewall.actualiserTOTO();
  12.       break;
  13.    case 4:
  14.       firewall.ouvrirTUTU();
  15.       break;
  16.    case 5:
  17.       firewall.fermerTUTU();
  18.       break;
  19.    case 6:
  20.       firewall.actualiserTUTU();
  21.       break;
  22. [etc...]
  23. }
  24. boutons[0].addActionListener(new OuvrirTOTOListener());
  25. boutons[1].addActionListener(new FermerTOTOListener());
  26. boutons[2].addActionListener(new OuvrirTUTUListener());
  27. boutons[3].addActionListener(new FermerTUTUListener());
  28. class OuvrirTOTOListener implements ActionListener{
  29.         public void actionPerformed(ActionEvent e){
  30.                  commande(1);
  31.                  commande(3)
  32.         }
  33. }
  34. class FermerTOTOListener implements ActionListener{
  35.         public void actionPerformed(ActionEvent e){
  36.                  commande(2)
  37.                  commande(3)
  38.         }
  39. }
  40. class OuvrirTUTUListener implements ActionListener{
  41.         public void actionPerformed(ActionEvent e){
  42.                  commande(4)
  43.                  commande(6)
  44.         }
  45. }
  46. class FermerCTUTUListener implements ActionListener{
  47.         public void actionPerformed(ActionEvent e){
  48.                  commande(5)
  49.                  commande(6)
  50.         }
  51. }


Peux-tu m'expliquer un peu plus ce que tu me proposes stp.
Je dois créer une classe Connection et une classe ConnectionAction ?
Que doivent-elles contenir en fait ?  :sweat:  
 
Merci de ton aide en tout cas !

Reply

Marsh Posté le 18-10-2014 à 12:55:49    

Bah, j'ai juste fait l'hypothèse que tu avais besoin d'une classe Connexion...
 
La notion de classe permet de génériciser le comportement en donnant des paramètres au constructeur.
 
Il n'y aucune logique à séparer la partie "commande" et la partie Listener.
 
Pour moi ce que tu veux faire c'est un Listener qui :
- Travaille sur une règle (ou port, peut importe) de firewall (TITI, TUTU)
- Qui exécute une des actions :
      * ouvrir
      * fermer
      * etc...
- Après l'action, il faut actualiser  
 
Donc pourquoi séparer le listener et la partie "commande" ? Pourquoi ta fonction commande ne fait pas partie de la classe Listener ?
 
De plus je n'ai pas l'utilisation des int pour les switch, je préfère  les enum, plus explicites (et typé surtout).
 
Et plutôt que de multiplier les fonctions dans GestionAccesFirewall  , j'aurais fait une fonction générique avec un enum.
J'aurais plutôt fait qq chose du style.
 

Code :
  1. public class GestionAccesFirewall{
  2.        public enum Access{
  3.                TOTO,
  4.                TUTU,
  5.                TITI;
  6.        }
  7.        public void ouvrir(Access access){
  8.             ...
  9.        }
  10.        public void fermer(Access access){
  11.             ...
  12.        }
  13.        public void rafraichir(Access access){
  14.             ...
  15.        }
  16.        .... //le reste du code existant
  17. }
  18. class GenericFirewallActionListener implements ActionListener{
  19.        public enum Action {
  20.                 OPEN,
  21.                 CLOSE;
  22.         }
  23.         GestionAccesFirewall.Access m_access;
  24.         Action m_action;
  25.         GestionAccesFirewall m_firewall;
  26.         public GenericFirewallActionListener(GestionAccesFirewall firewall,GestionAccesFirewall.Access access, Action action) {
  27.                m_firewall = firewall;
  28.                m_access = access;
  29.                m_action = action;
  30.         }
  31.         public void actionPerformed(ActionEvent e){
  32.                  switch(m_action){
  33.                         case OPEN :m_firewall.open(m_access);break;
  34.                         case CLOSE:m_firewall.fermer(m_access);break;
  35.                  }
  36.                  m_firewall.rafraichir(m_access);
  37.         }
  38. }


 
Et pour l'initialisation c'est simple (et plus générique) : il suffit de boucler sur les accès "exposés" par la classe GestionAccessFirewall et les actions du listener.

Code :
  1. GestionAccessFirewall firewallManager = ...;
  2. List<JRadioButton> listButton=...;
  3. for(GestionAccesFirewall.Access access:  GestionAccesFirewall.Access.values){
  4.       for(GenericActionListener.Action action: GenericActionListener.Action.values()){
  5.          JRadioButton button = new ...;
  6.          listButton.add(button);
  7.          ...
  8.          button.addActionListener(new GenericFirewallActionListener(firewallManager,access,button);
  9.       }
  10. }


 
 
Et comme ça, tu construits ton interface automatiquement à chaque fois que tu créées une action ou une règle d'accès dans ton code.
 
Ce n'est qu'une approche, mais l'idée avec la gestion par classe est d'éviter la démultiplication du code.
 
J'espère que ça répond au problème ou au moins que ça t'ouvre de nouvelles pistes de structuration de ton code.

Reply

Marsh Posté le 23-10-2014 à 10:58:07    

Merci beaucoup !! Yu m'as bien mis sur la voie et ça m'a permis de découvrir la puissance des enum !! :D  
 
Dernière question :  actuellement j'ai ça  

Code :
  1. public class GestionAccesFirewall{
  2.        public enum Access{
  3.                TOTO("aaaa","1111" ),
  4.                TUTU("bbbb","2222" ),
  5.                TITI("cccc","3333" );
  6.        private String s1="";
  7.        private String s2="";
  8.      
  9.        Acces(String a, String b){
  10.               this.s1 = a;
  11.               this.s2 = b;
  12.       }
  13.       }
  14. }


 
Je voudrai pouvoir ajouté d'autres String à mes objets TOTO, TUTU... mais sans que le nombre de ces string soit défini, exemple :

Code :
  1. public enum Access{
  2.         TOTO("aaaa","1111","toto" ),
  3.         TUTU("bbbb","2222","tutu","titi","tata" ),
  4.         TITI("cccc","3333","tuti","tato" );
  5.         ...etc
  6. }


J'imaginai donc un constructeur dans le genre de

Code :
  1. Acces(String a, String b, String[] tab)


ou

Code :
  1. Acces(String a, String b, List<String> liste)


pour récupérer mes String et pouvoir les utiliser dans mon code, mais je bloque...  :??:  :whistle:  
 
Comment puis-je faire cela ?
 
EDIT :
J'ai trouvé, en faisant une ellipse :

Code :
  1. public enum Access{
  2.         TOTO("aaaa","1111","toto" ),
  3.         TUTU("bbbb","2222","tutu","titi","tata" ),
  4.         TITI("cccc","3333","tuti","tato" );
  5.        
  6.        private String s1="";
  7.        private String s2="";
  8.        private String[] tab;
  9.    
  10.        Acces(String a, String b, String... m_strings){
  11.               this.s1 = a;
  12.               this.s2 = b;
  13.               this.tab = m_strings
  14.       }
  15. }


Message édité par sebastien4444 le 23-10-2014 à 13:14:57
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed