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

Java Discussion :

Appel de méthode par adresse, liaison tardive ou dynamic cast


Sujet :

Java

  1. #1
    Membre régulier
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Octobre 2009
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2009
    Messages : 167
    Points : 118
    Points
    118
    Par défaut Appel de méthode par adresse, liaison tardive ou dynamic cast
    Bonjour,

    Je souhaite centraliser la gestion des évènements qui surviennent dans un JFrame, dans le cadre de boutons, menus, etc. Pour cela je crée une classe cEventManager (qui est à l'extérieur du JFrame et qui est utilisée pour créer les boutons, menus, etc.), qui reçoit et stocke le JFrame en tant qu'Object.

    Je souhaite faire cela sans la réflexion, car j'envisage de développer pour Android, dont les VM n'implémentent pas la réflexion.

    Je voudrais lorsque qu'un évènement surgit (click sur un bouton dans le JFrame), que l'objet issu de la classe cEventManager appelle le JFrame (stocké comme Object) sur une méthode qui est implémentée par défaut dans le JFrame(EventManager).

    Mon pb est le suivant :

    MonJFrame.EventManager(mes_params) fonctionne bien si MonJFrame est casté (impossible de faire une liaison tardive) :
    ((JFrame).MonJFrame.EventManager(mes_params);
    Il faut donc que je caste dans le dur.

    Puis-je caster dynamiquement, c'est à dire qu'une "trouvaille" permette de détecter et caster à partir de MonJFrame ?

    Autre solution :
    Je pourrais passer l'adresse de MonJFrame.EventManager(), et ensuite faire un appel par adresse (comme en C). Est-ce possible en Java (je n'ai rien trouvé) ?

    Autre solution : faire un CallByName comme en VB. Mais là j'ai trouvé sur le Net que c'est impossible sans la réflexion.

    Vos idées sont les bienvenues...

    Merci.

    Christian

  2. #2
    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
    Il suffit de ne pas stocker comme Object, mais comme la bonne classe...

    Tout ça pour ça... -_-°

    Et non, on ne peut pas appeler par adresse. Mais il reste possible d'appeler par nom ou avec un fonctor à la place de l'adresse... Sauf qu'il y a pas besoin de tout ça, il suffit de faire les choses correctement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Octobre 2009
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2009
    Messages : 167
    Points : 118
    Points
    118
    Par défaut
    Je suis d'accord, mais le projet est de centraliser tous types de classes. Et c'est là que les pb commencent.

  4. #4
    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
    Comprends pas ce que tu dis, mais il n'y a pas de problème. Au pire il faut utiliser les génériques.

    Donne du vrai code au lieu de parler, si tu crois qu'il y a un problème.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre régulier
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Octobre 2009
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2009
    Messages : 167
    Points : 118
    Points
    118
    Par défaut
    Tu as raison :

    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
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    import java.awt.event.ActionEvent;
    import javax.swing.AbstractAction;
     
    public class cEventManager extends AbstractAction {
     
    private String m_key;
    private Object m_owner;
    private String m_owner_classname;
     
    	public cEventManager(Object Owner, String Key, String texte){
    		super(texte);
    		m_key = Key;
    		m_owner = Owner;
    		m_owner_classname = Owner.getClass().getName();
    	}
     
    	public void actionPerformed(ActionEvent e) { 		
    		if ( m_owner_classname=="_Form") {((_Form) m_owner).EventManager (m_key, e);}
     
    	} 
     
    }
     
     
    import javax.swing.SwingUtilities;
     
    public class StartUp {
     
    	public static void main(String[] args) {
    		SwingUtilities.invokeLater(new Runnable(){
    			public void run(){
    				_Form fenetre = new _Form("StartUp");
    			}
    		});
    	}
     
    }
     
     
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Label;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
     
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.prefs.Preferences;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
    import javax.swing.event.MenuEvent;
    import javax.swing.event.MenuListener;
     
    public class _Form extends JFrame {
     
    	public _Form( String Title) {
    		super();
    		addListeners();
    		this.setTitle(Title);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		Preferences prefs = Preferences.userNodeForPackage(_Form.class);
    		int x = prefs.getInt("x",200);
    		int y = prefs.getInt("y",200);
    		this.setLocation(x,y);
     
    		int w = prefs.getInt("w",200);
    		int h = prefs.getInt("h",200);
    		this.setSize(w,h);
     
    		setContentPane(buildContentPane());
     
    		this.setVisible(true);
    	}
     
    	private JPanel buildContentPane(){
    		JPanel panel = new JPanel();
    		panel.setLayout(new FlowLayout());
    		panel.setBackground(Color.white);
     
    		JMenuBar menuBar = new JMenuBar();
     
    		JMenu menu1 = new JMenu(new cEventManager( this, "mnMain", "Menu principal"));
    		menuBar.add(menu1);
     
    		JMenuItem calculer = new JMenuItem(new cEventManager( this, "mnCalculer", "Je calcule maintenant !"));
    		menu1.add(calculer);
     
    		JMenuItem quitter = new JMenuItem("Quitter");
    		menu1.add(quitter);
     
    		setJMenuBar(menuBar);
     
    		return panel;
    	}
     
     
    	public void EventManager(String Key, ActionEvent e){
    		System.out.println(Key + " clicked");
    	}
     
    	private void addListeners(){
    		addWindowListener(new WindowAdapter(){
    			public void windowClosing(WindowEvent we){
    				Preferences prefs = Preferences.userNodeForPackage(_Form.class);
    				Rectangle bounds = getBounds();
    				prefs.putInt("x",(int)bounds.getX());
    				prefs.putInt("y",(int)bounds.getY());
    				prefs.putInt("w",(int)bounds.getWidth());
    				prefs.putInt("h",(int)bounds.getHeight());	
    			}	
    		});
    	}
     
    }
    3 Classes :

    1. StartUp qui est le main,
    2. _Form qui est une feuille "standard", et qui va s'afficher avec son menu
    3. cEventManager qui est la fameuse classe qui doit gérer tout les évènements de l'appli.


    _Form représente la feuille de fond de l'appli. Mais il peut y avoir bien d'autres feuilles (modales, bulle d'aide, splash, msgbox, etc.)

    Lorsque qu'un menu est créé, la gestion des évènements est confiée à cEventManager.

    Tout le pb consiste à renvoyer vers la feuille qui contient le menu, l'information qu'un évènement a eu lieu, avec des paramètres lambda.

    Le pb est qu'il peut y avoir plusieurs feuilles, de types différents, et que je souhaite n'avoir qu'une seule classe de gestion des évènements pour toute l'appli.

    Dans cet exemple, je récupère le nom de la classe à l'installation du gestionnaire d'évènement, puis lorsqu'un évènement survient, je fais un test pour savoir comment caster. Cela n'est vraiment pas élégant.

    Christian

  6. #6
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Tu es un peu en train de réinventer la roue mais bon.
    D'apres ton exemple, tu cherches à notifier tes form d'une action en appelant une fonction public void EventManager(String Key, ActionEvent e).
    Le plus simple est de créer une interface "MonListener" qui définit cette méthode. Dans le constructeur de cEventManager, remplacer le type de Owner et de m_owner par "MonListener".
    Pour finir, faire que les classes Form et celles qui ont besoin d'etre notifiées implémentent MonListener.
    Comme ca, finit les bidouilles immondes.

    Note que cela ne fonctionne que si tous tes listeners utilisent des ActionEvent. Si ce n'est pas le cas, avant de partir sur une autre bidouille, il faudrait préciser quels peuvent etre les parametres envoyés et d'ou ils viennent. Ce que tu fais à l'air d'etre un probleme Object classique et n'a pas besoin de reflexion ou autre...

  7. #7
    Membre régulier
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Octobre 2009
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2009
    Messages : 167
    Points : 118
    Points
    118
    Par défaut
    Un grand merci.

    Cela fonctionne très bien. Je n'ai pas tout compris et je vais donc m'y intéresser de très près.

    Christian

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

Discussions similaires

  1. plugin perso, appel une méthode par un string
    Par splifferwolf dans le forum jQuery
    Réponses: 3
    Dernier message: 27/11/2011, 13h17
  2. Appeler une méthode par son nom sans utiliser eval
    Par rambc dans le forum Général Python
    Réponses: 5
    Dernier message: 30/10/2009, 16h05
  3. Imbriquer les appels de fonctions par adresse
    Par TheDrev dans le forum C
    Réponses: 5
    Dernier message: 10/10/2008, 23h39
  4. [Framework] Appel d'une méthode par Spring
    Par badi082 dans le forum Spring
    Réponses: 3
    Dernier message: 03/06/2008, 12h07
  5. Appel du navigateur par défaut et méthode POST
    Par Pascal Fonteneau dans le forum Web & réseau
    Réponses: 2
    Dernier message: 23/01/2008, 07h56

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