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

Codes sources à télécharger Java Discussion :

JMenu : ActionListener unique pour toutes les items d'un menu, et lance le traitement voulu pour chacune.


Sujet :

Codes sources à télécharger Java

  1. #1
    Membre régulier

    Homme Profil pro
    Enseignant
    Inscrit en
    février 2020
    Messages
    122
    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 : 122
    Points : 108
    Points
    108
    Par défaut JMenu : ActionListener unique pour toutes les items d'un menu, et lance le traitement voulu pour chacune.
    Bonjour,

    Je vous propose un nouvel élément à utiliser : JMenu : ActionListener unique pour toutes les items d'un menu, et lance le traitement voulu pour chacune.

    Après plusieurs recherches et échanges, je n'ai pas trouvé une manière efficace pour gérer les déclenchements sur une JMenuItem de manière concise.

    En effet, on conseille de faire pour chaque item, un ActionListener spécifique à cette item, qui fera le traitement voulu.

    L’inconvénient est que le code se répète, presque identique pour chaque JMenuItem, et cela devient lourd et difficilement lisible pour moi...

    C'est le cas du premier menu de ma source, le menu "fichier", pas élégant et peu engageant à décoder.





    Après du temps et des essais, j'ai préféré utiliser le membre natif "name", de chaque JMenuItem, pour identifier de manière unique chaque item.

    Après déclenchement par un clic sur une JMenuItem, je recherche l'objet source du déclenchement, je le caste en JMenuItem, et je peux en lire la valeur du membre "name" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String nom =  ((JMenuItem) e.getSource()).getName();
    L'item est identifié et on peut démarrer le traitement spécifique voulu sur cette item.

    C'est le cas du menu "Edition" de la source proposée.

    L'avantage est que le "ActionListener" est le même pour toutes les items du menu et pourtant, le lancement de l'action reste spécifique à l'item cliquée.





    Autre approche possible non fournie ici : on peut identifier la JMenuItem, à l'aide d'un entier.

    Pour cela je vois deux solutions :



    1/ On analyse la chaine du membre "name" et on l’interprète comme un integer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String i = ((JMenuItem) e.getSource()).getName();
    int k = Integer.parseInt (i);

    2/ on crée sa propre classe MesJMenuItem par exemple, qui étendent les JMenuItem natives, et on leur ajoute un membre : int numItem = 12, par exemple, et on détecte alors ce membre dans le ActionListener unique pour lancer les traitements spécifiques.





    Voila, n'ayant pas trouvé cela clairement, je vous propose ces idées, car pour moi, je trouve qu'un ActionListener unique pour toutes les JMenusItems, est plus clair et allège mes menus.



    N'hésitez pas à me donner vos avis, même s'ils sont critiques bien sur!....



    Qu'en pensez-vous ?

  2. #2
    Membre averti
    Homme Profil pro
    Architecte technique
    Inscrit en
    mai 2020
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : mai 2020
    Messages : 246
    Points : 319
    Points
    319
    Par défaut
    Comme je vous le disait de le post initial, l'utilisation la plus courante est d'avoir des sous classes de Action. C'est d'ailleurs l'approche proposée par Oracle dans les tutoriels Swing: https://docs.oracle.com/javase/tutor...sc/action.html

    Les avantages sont:
    + Un typage fort. Le refactoring est facile car votre Ide peut identifier les utilisations de la classe (Contrairement à une solution basée sur des String ou les erreurs de typos sont faciles)
    + Une clareté du code. Une new JMenuItem(new SetColorAction(Color.BLUE, selection)) me semble plus claire que new JMenuItem("Blue", new MultiAction())
    + Une action est réutilisable et cohérente. Si je change l'icône de l'action, tous les boutons et menus qui l'utilisent seront mis à jour.

    Les désavantages:
    + C'est verbeux (à vérifier*)
    + Ca ne vous convient pas.


    Je cois que la solution réside dans le dernier désavantage: "Ca ne vous convient pas".
    Java est un langage très large, qui permet de faire beaucoup de choses et qui n'impose pas trop de contraintes. C'est une faiblesse mais aussi une force. Au vu du décalage entre votre première question et celle-ci, il est clair que vous avez pris le temps de réfléchir et de chercher la solution qui vous convient le mieux. Gardez alors celle qui vous convient. L'essentiel étant, de faire ce qui vous semble le mieux car c'est vous qui travaillez sur ce projet et c'est vous qui le connaissez le mieux.

    Ce que vous pourriez-faire c'est vous poser la question de comment améliorer les choses. Vous pourriez peut-être utiliser une enum pour tous les noms d'actions, ça simplifierais le réfactoring et limiterais les erreurs de typos. Peut-être même créer une JMenuItem qui n'attends en paramètre qu'une seule valeur de l'enum (ou plusieurs si ce menu doit faire plusieurs actions en une) et/ou créer vos menus sur base de cette enum via une boucle qui crée un item pour chaque valeur de l'enum (ca ne fonctionneras pas pour les sous menu car un enum n'est pas hierachique).

    Le name à d'autres utilités. Par contre la clef/constante https://docs.oracle.com/javase/8/doc...ON_COMMAND_KEY est souvent utilisée pour identifier l'action.

    Vous pourriez aussi aller plus loin et faire de votre ActionListener unique le centre de votre application, un peu comme ce que l'on trouve dans le web avec Redux qui centralise les actions tout en séparant une action de ces effets.


    ----

    * On peut créer des sous classes pour limiter la répétition, les détails du comportement sont alors définis par les paramètres du constructeur. new SetColorAction(Color.BLUE); new SetColorAction(Color.RED); ..
    Est-ce que la suite de if("SetColorToBlue".equals(menu.getName()) est vraiment plus lisible, moins verbeuse et risqué que quelques classes ?
    Avec plusieurs actions, vous pouvez simplifiez votre code:

    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
     
    // Avant, tout est défini dans le menu
    JMenuItem menuOpenFile = new JMenuItem("Open File ...");
    menuOpenFile.setIcon(new ImageIcon("icones/open.png"));
    menuOpenFile.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            MyWindow.affichage.append("on a déclenché le listener spécifique à  l'item :         Open File \n");
        }
    });
    menuFile.add(menuOpenFile);
     
    // Après, l'action définit son comportement mais aussi son nom, icone.
    // -- OpenFileAction.java
    class OpenFileAction extends AbstractAction {
     
        public OpenFileAction() {
            super("Open File ...", new ImageIcon("icones/open.png"));
        }
     
        @Override
        public void actionPerformed(ActionEvent e) {
            MyWindow.affichage.append("on a déclenché le listener spécifique à  l'item :         Open File \n");
        }
    }
     
    // -- CreateJMenuBar.java
    menuFile.add(new OpenFileAction());
    Personellement, je défini comme vous une sous classe de JMenuBar mais je découpe la création des menus dans différentes méthodes ou via des sous classes de JMenu quand le menu est particulier.

  3. #3
    Membre régulier

    Homme Profil pro
    Enseignant
    Inscrit en
    février 2020
    Messages
    122
    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 : 122
    Points : 108
    Points
    108
    Par défaut merci gervais.b
    bonjour gervais.b,

    merci tout d'abord pour la remise en forme de mon message et pour le temps passé pour votre analyse et tous ces nouveaux éléments.

    J'ai passé pas mal de temps à tenter des choses dans mes menus, car c'est vrai qu'un listener à la volée, pour chaque item, ça me perturbe...(j'ai un cerveau de post-cinquantenaire, et donc, une approche personnelle un peu rigide, difficile à modifier)

    Votre vision me permet d'avancer peu à peu, mais plus j'en découvre et que j'ai l'impression d’améliorer certaines spécificités, plus je ressens que les possibilités peuvent s'étendre au-delà, sans pour autant en avoir la maitrise pour le moment, mais c'est aussi cela qui est intéressant...

    Encore merci et peut-être à bientôt pour de nouvelles difficultés à évoquer..

  4. #4
    Membre averti
    Homme Profil pro
    Architecte technique
    Inscrit en
    mai 2020
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : mai 2020
    Messages : 246
    Points : 319
    Points
    319
    Par défaut
    Citation Envoyé par patdu26 Voir le message
    car c'est vrai qu'un listener à la volée, pour chaque item, ça me perturbe...
    C'est peut-être ça le problème. Ne voyez pas juste un listener qui délégue son comportement à quelquechose mais bien une action réutilisable. Vous pourriez aussi étendre vos actions pour les réutiliser ne dehors de Swing, via une application web ou une ligne de commande.

    L'idée est vraiment de définir une classe "autonome" pour chaque action, pas juste un listener. Mais, encore une fois, ce qui fonctionne c'est ce qui vous convient.

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

Discussions similaires

  1. [XL-2010] VBA slicer, voir si tout les items sont selectionnés
    Par halaster08 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 21/12/2016, 16h00
  2. comment copier les items d'un menu dans un autre ?
    Par thierrybo dans le forum Débuter
    Réponses: 2
    Dernier message: 17/09/2010, 17h01
  3. Les items d'un menu dans une page séparée
    Par Nerva dans le forum Général Conception Web
    Réponses: 4
    Dernier message: 04/01/2010, 13h52
  4. Espacement entre les items d'un menu
    Par Thrud dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 03/06/2008, 13h52
  5. lien entre les items d'un menu en javascript et les servlets
    Par Smix007 dans le forum Services Web
    Réponses: 2
    Dernier message: 26/01/2007, 15h26

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