Passer méthode comme paramètre [Résolu/Fermé]

Signaler
Messages postés
24
Date d'inscription
mercredi 6 mai 2009
Statut
Membre
Dernière intervention
22 août 2013
-
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
-
Bonjour,
Je suis encore face à un problème !
Pour diminuer la quantité de lignes de code dans une classe, j'aimerais créer une méthode dont certains paramètres seront adaptés/changés à l'aide d'un switch case.
Ce qui implique (enfin, je pensais) de devoir passer une méthode en paramètre.
Je suis aller voir sur le net et j'ai trouvé ceci, mais ça ne fonctionne pas pour mon problème.
Voici une partie de mon code pour faciliter la compréhension:
switch(listNr){
case 2:
test();
break;
case 3: test();
break;
case 4: test();
break;
}

private void test(String listName, Class classe, Methode methode, GraphicsConfiguration gConfig){
String shortListName = listName.substring(3);	//permet d'enlever les 2 --
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(ctb.getJPanelManageClients().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, ctb.getJPanelManageClients(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(ctb.getJPanelManageClients());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
if(view.isVisible()==false) view.setVisible(true);	
if(ctb.getJPanelManageClients().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, ctb.getJPanelManageClients(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(ctb.getJPanelManageClients());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}
}


Bien sûr, dans l'appel de la méthode 'test' du switch case, je dois y inclure les paramètres ad hoc.
Et dans la méthode 'test', le paramètre 'methode' dois remplacer la méthode 'getJPanelManageClients()'.
Est-ce que ma démarche est possible (j'espère avoir été assez clair ) !
PS: la méthode test(), permet d'ouvrir des JTabbedPane
Merci d'avance.

Marc

11 réponses

Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
Pour la peine, voilà comment faire :


/**
 * Interface definissant la méthode commune
 * (celle que tu souhaiterais passer en parametre)
 */
public interface IEtat{

public void methode();	

}

/**
 * Définition de la premiere méthode dans une classe particulière
 */
public class Etat1 implements IEtat {

public void methode(){
System.out.println("1");
}	

}

/**
 * Idem
 */
public class Etat2 implements IInterface {

public void methode(){
System.out.println("2");
}	

}

public class Classe {

/**
 * Tu peux passer un IEtat en parametre
 * Si tu passes une classe de type etat2, 2 sera affiché à la console
 * Si c'est une classe etat1, 1 sera affiché à la console
 */
public void autreMethode(IEtat etat){
etat.methode();
}

}
Messages postés
2116
Date d'inscription
samedi 8 novembre 2003
Statut
Contributeur
Dernière intervention
6 octobre 2012
10
salut...

et dans tous ca !!! qu es qui ne fonctionne pas?? ;o)
qu es ce que tu veux ??? qu es ce que tu as??? ... ;o)


PS : dans un switch case on fait toujours.......... apelle à une methode ... ;o) pour plus de clarté dans la lecture du code un case qui dépase les 3 ou 4 lignes est un mauvais case... ;o)

GodConan ;o)
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
Bonjour,

En java, impossible de passer une méthode en paramètre mais par contre, tu peux utiliser le design pattern factory qui te permettra de pallier au problème. Tu peux faire des recherches sur internet, tu trouveras comment l'utiliser.
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
Je m'excuse mais je me suis trompé de design pattern, ce n'est pas factory mais State.
Messages postés
24
Date d'inscription
mercredi 6 mai 2009
Statut
Membre
Dernière intervention
22 août 2013

Merci pour votre aide,

Si je comprends bien le principe du Pattern State, je devrai créer autant de classe (ici par ex. Etat1) que j'ai de différente méthode ! Mon but était de simplifier le code mais dans ce cas, j'auerai 10 à 15 classe rien que pour gérer le passage d'une méthode !!! Est-ce bien résonnable ?
J'ai ça comme code actuellement (qui fonctionne):
switch(listNr){
case 2: listName = "Liste des clients";
break;
case 3: listName = "Liste des groupes";
break;
case 4: listName = "Liste des sociétés";
break;
case 6: listName = "Liste des réservations";
break;

}	
if(listNr == 2/* listName.equalsIgnoreCase("-- Liste des clients")*/){
String shortListName = listName/*.substring(3)*/;	//permet d'enlever les 2 --
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(ctb.getJPanelManageClients().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, ctb.getJPanelManageClients(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(ctb.getJPanelManageClients());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
if(view.isVisible()==false) view.setVisible(true);	
if(ctb.getJPanelManageClients().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, ctb.getJPanelManageClients(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(ctb.getJPanelManageClients());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}

}
else if(listNr == 3/* listName.equalsIgnoreCase("-- Liste des sociétés")*/){
String shortListName = listName/*.substring(3)*/;	//permet d'enlever les 2 --
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(cotb.getJPanelManageCompany().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, cotb.getJPanelManageCompany(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(cotb.getJPanelManageCompany());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
//				System.out.println("pas nul");
if(view.isVisible()==false) view.setVisible(true);
if(cotb.getJPanelManageCompany().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, cotb.getJPanelManageCompany(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(cotb.getJPanelManageCompany());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}
}else if(listNr == 4/*listName.equalsIgnoreCase("-- Liste des groupes")*/){
String shortListName = listName/*.substring(3)*/;	//permet d'enlever les 2 --
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(gtb.getJPanelManageGroups().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, gtb.getJPanelManageGroups(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(gtb.getJPanelManageGroups());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
if(view.isVisible()==false) view.setVisible(true);
if(gtb.getJPanelManageGroups().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, gtb.getJPanelManageGroups(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(gtb.getJPanelManageGroups());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}
}else if(listNr == 6/*listName.equalsIgnoreCase("-- Liste des réservations")*/){
String shortListName = listName/*.substring(3)*/;	//permet d'enlever les 2 --
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(rtb.getJPanelManageReservation().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, rtb.getJPanelManageReservation(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(rtb.getJPanelManageReservation());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
if(view.isVisible()==false) view.setVisible(true);
if(rtb.getJPanelManageReservation().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(shortListName, null, rtb.getJPanelManageReservation(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(rtb.getJPanelManageReservation());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}

}

et ce code augmente à chaque fois que je voudrai un JTabbedPane en plus.
C'est pour ça que je voulais passer à la solution d'une seule méthode (test()).
De plus, dans cette méthode test(), je devrai passer autre chose (en plus) qu'une méthode en paramètre...
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
Non, ce n'est pas raisonnable vu ton code. Il y a déjà bien d'autres choses à améliorer.

Déjà commence par enlever tous les

}else{
//sinon rien
}



Qui ne servent à rien.

Ensuite tu n'as pas vraiment de conception objet donc, implémenter un pattern state, serait assez étrange ;)
Messages postés
24
Date d'inscription
mercredi 6 mai 2009
Statut
Membre
Dernière intervention
22 août 2013

Finalement, j'ai essayé avec le State Pattern et ça fonctionne comme je voulais. Super !
Voici mon code pour la forme :
switch(listNr){
case 2:
activePanel("Liste des clients", state = new ClientTabBis(this.mainView, facade), gConfig);
break;
case 3: activePanel("Liste des groupes", state = new GroupTabBis(this.mainView, facade), gConfig);
break;
case 4: activePanel("Liste des sociétés", state = new CompanyTabBis(this.mainView, facade), gConfig);
break;
case 6: activePanel("Liste des réservations", state = new ReservationTabBis(this.mainView, facade), gConfig);
break;
}

private void activePanel(String listName, IStateTabBis state, GraphicsConfiguration gConfig){
if(view==null){	//si le 'JFrame' est deja ouvert, il n'essaye plus de l'ouvrir
view = new Manage_jTabbedPaneMainBis(facade, gConfig);
if(state.getJPanelMain().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(listName, null, state.getJPanelMain(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(state.getJPanelMain());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}else{
if(view.isVisible()==false) view.setVisible(true);	
if(state.getJPanelMain().isValid()==false){	//si le panneau est deja actif, il n'essaye plus de l'activer
view.getJTabbedPaneMain().addTab(listName, null, state.getJPanelMain(), BorderLayout.CENTER);
view.getJTabbedPaneMain().setSelectedComponent(state.getJPanelMain());	//permet d'activer l'onglet que l'on ajoute grace a un bouton
for(int i = 0; i < view.getJTabbedPaneMain().getTabCount(); i++){
view.getJTabbedPaneMain().setTabComponentAt(i, new ButtonTabComponent(view.getJTabbedPaneMain()));
}
}else{
//sinon rien
}
}
}

où j'ai nommé l'Interface 'IStateTabBis' et la méthode commune 'public JPanel getJPanelMain();'.

Encore merci, sans votre aide, je n'aurais jamais passé à ça !
Salut.

Marc
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
En général, quand tu as un code qui contient une suite de if, ce design pattern permet de le simplifier.

Par contre, tu augmentes le nombre de classes. Mais c'est un peu comme ca que fonctionnent tous les design pattern, augmenter le nombre de classes pour diminuer la complexité de chaque classe.

Si tu respectais les normes de codage en java, ce serait vraiment bien :

Manage_jTabbedPaneMainBis -> ManageJTabbedPaneMainBis par exemple

et supprimes les :
}else{
//sinon rien
}
qui sont ridicules.

Tu peux également remplacer if(state.getJPanelMain().isValid()==false) par if(!state.getJPanelMain().isValid())

De plus, tes commentaires n'aident pas, ils rendent le code difficile à lire, je te conseil plutôt d'utiliser la java doc et de le faire au dessus des méthodes uniquement.
Messages postés
1
Date d'inscription
jeudi 8 novembre 2007
Statut
Membre
Dernière intervention
22 novembre 2011

Même en java il est possible de faire un appel d'une méthode via juste son nom (un String) on appel cela la "reflection"

ci dessous un exemple simple :

public static void main(String args[])
{
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod(
"add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj
= meth.invoke(methobj, arglist);
Integer retval = (Integer)retobj;
System.out.println(retval.intValue());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
Messages postés
2116
Date d'inscription
samedi 8 novembre 2003
Statut
Contributeur
Dernière intervention
6 octobre 2012
10
non .. ce n est pas cela la reflexion ;o) ... enfin cela ne set pas à ca.. ;o)

GodConan ;o)
Messages postés
6414
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
29 juillet 2020
312
Bonjour,

Je clos le sujet, merci de ne pas polluer les post ouverts par d'autres. Ouvres un nouveau sujet pour poser tes questions.