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

AWT/Swing Java Discussion :

Ordre d'exéccution de Listeners


Sujet :

AWT/Swing Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 265
    Points : 149
    Points
    149
    Par défaut Ordre d'exéccution de Listeners
    Bonjour,

    Je n'ai pas trouvé de solution pour le problème suivant.

    J'ai défini une JList. Lorsque je double-clic sur une ligne je veux exécuter la méthode "retour();"
    Par contre avec un simple clic je souhaite soit sélectionner une ou plusieurs lignes, soit les dé-sélectionner.

    Pour ce faire, j'ai défini un listener et un modèle mais c'est toujours une déselection qui survient même si je double clique.


    Plutôt que d'avoir un listener, peut-on tester l'exécution d'un double clic dans une méthode du modèle. Toutes suggestions seront les bienvenues.


    Merci d'avance

    Gégé

    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
     
     
                            Personnes = new JList();
    			Personnes.setName("Personnes");
    			Personnes.setFont(new java.awt.Font("Arial", 1, 12));
    			Personnes.setForeground(java.awt.Color.white);
    			Personnes.setDragEnabled(false);
     
     
     
                    Personnes.addMouseListener(new MouseAdapter() 
    		{
    			public void mouseClicked(MouseEvent e)
    			{
    			   if ( e.getClickCount() == 2) 
    			   {
    				 	 retour();
    			   }
    			}
    		});
     
     
                    Personnes.setSelectionModel(new DefaultListSelectionModel() 
    		 {
    			private static final long serialVersionUID = 1L;
     
    			public void setSelectionInterval(int index0, int index1) {
    		        if (index0 == index1) {
    		          if (isSelectedIndex(index0)) {
    		            removeSelectionInterval(index0, index0);
    		            return;
    		          }
    		        }
    		        super.setSelectionInterval(index0, index1);
    		      }
     
    		      @Override
    		      public void addSelectionInterval(int index0, int index1) {
    		        if (index0 == index1) {
    		          if (isSelectedIndex(index0)) {
    		            removeSelectionInterval(index0, index0);
    		            return;
    		          }
    		          super.addSelectionInterval(index0, index1);
    		        }
    		      }
     
    		    });

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 12 430
    Points : 29 128
    Points
    29 128
    Billets dans le blog
    2
    Par défaut
    Salut,

    L'ordre d'exécution des écouteurs, c'est l'ordre de l'enregistrement de ces écouteurs.


    Si je comprends bien ce que tu cherches à faire, c'est ne pas perdre la sélection lorsqu'on double-clique. Le souci c'est qu'un double-clic, c'est deux clics. Donc quand on double-clique, ça déclenche l'écouteur dédié à la sélection 2 fois et on perd la sélection, puisque ça la refait de zéro, deux fois). Le composant JList n'a pas été vraiment prévu pour autre chose que de faire de la sélection (il n'y a pas d'ActionListener sur une JList).

    La seule solution que je vois, c'est de mémoriser la sélection et de la restaurer en cas de double-clic. Cela pose un second souci : pour mémoriser la sélection, il faut le faire avant que la JList la change. On pourrait le faire après, mais ça oblige à savoir qu'elle a été faite, pour savoir s'il faut la restaurer, avec le problème de savoir quand elle est faite mais qu'on veut pas qu'elle le soit en fait. Le faire avant est beaucoup plus simple. Enfin, comme on double-clique, donc on clique deux fois, il faut la mémoriser deux fois, et restaurer la première des deux.

    Pour le faire avant que l'écouteur dédié à la sélection change la sélection, on va simplement supprimer les écouteurs, enregistrer celui qui sert à mémoriser, remettre les écouteurs par défaut, puis celui du double-clic.

    Il y a un troisième souci : la sélection ne se gère pas par clic, mais par mousePressed et mouseReleased. Seulement, c'est fait dans le composant d'UI (le BasicListUI). Rien ne dit que quelque soit le Look And Feel, les écouteurs fonctionnent toujours comme ça. Mais je pars du principe qu'à moins de changement fondamentaux dans le fonctionnement de la JList, ça devrait être le cas (faut se méfier quand même de certaines plateformes).

    Et pas besoin de toucher au modèle de sélection.

    1. Mémoriser et supprimer les écouteurs existants :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      MouseListener[] adapters = list.getMouseListeners();
       
      for (int i = 0; i < adapters.length; i++) { 
          list.removeMouseListener(adapters[i]);
      }
    2. Enregistrer un écouteur pour sauvegarder la sélection :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      list.addMouseListener(new MouseAdapter()  {
       
          public void mousePressed(MouseEvent e) { 
              selection.save(list,e);
          }
       
       
      });
    3. Remettre les écouteurs qu'on a enlevés :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      for (int i = 0; i < adapters.length; i++) { 
              list.addMouseListener(adapters[i]);
      }
    4. Enregistrer l'écouteur du double-clic qui va restaurer la sélection :
      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
      list.addMouseListener(new MouseAdapter()  {
       
       
          public void mouseClicked(MouseEvent e) {
       
              if ( e.getClickCount() == 2 && !keyPressed(e) && !e.isPopupTrigger() ) { 
                  selection.restore(list);
                  retour(); 
              } 
       
          }
       
          private boolean keyPressed(MouseEvent e) {
              return e.isAltDown() || e.isShiftDown() || e.isAltDown() || e.isAltGraphDown() || e.isControlDown() || e.isMetaDown() ;
          } 
       
      });
    5. Pour gérer la (double) sauvegarde et la restauration, j'utilise une classe :
      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
      class Selection {
       
          private int[] saved1 = {};
          private int[] saved2 = {};
       
          public void save(JList<?> list, MouseEvent e) {
              saved1 = saved2;
              saved2 = list.getSelectedIndices();
          }
       
          public void restore(JList<?> list) {
              list.setSelectedIndices(saved1);
          }
       
      }


    Il y a un petit défaut c'est qu'au premier clic, on voit la sélection disparaître. Je n'ai pas d'idée simple pour résoudre le problème.

    L'exemple fonctionnel complet :

    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
     
    import java.awt.Component;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.stream.IntStream;
     
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.JOptionPane;
    import javax.swing.ListSelectionModel;
    import javax.swing.SwingUtilities;
     
    public class MainJListExample {
     
    	public static void main(String[] args) {
     
    		JFrame frame = createFrame();
    		SwingUtilities.invokeLater(() -> {
    			frame.pack();
    			frame.setLocationRelativeTo(null);
    			frame.setVisible(true);
    		});
     
    	}
     
    	private static JFrame createFrame() {
    		JFrame frame = new JFrame("Exemple");
    		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
     
    		frame.add(createJList());
     
    		return frame;
    	}
     
    	private static Component createJList() {
     
    		String[] data = IntStream.range('A', 'Z').mapToObj(c -> Character.toString((char) c)).toArray(String[]::new);
     
    		JList<String> list = new JList<>(data);
    		list.setFont(list.getFont().deriveFont(list.getFont().getSize2D()*4));
    		list.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
     
    		list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
     
    		MouseListener[] adapters = list.getMouseListeners();
    		for (int i = 0; i < adapters.length; i++) {
    			list.removeMouseListener(adapters[i]);
    		}
     
    		class Selection {
     
    			private int[] saved1 = {};
    			private int[] saved2 = {};
     
    			public void save(JList<?> list, MouseEvent e) {
    				saved1 = saved2;
    				saved2 = list.getSelectedIndices();
    			}
     
    			public void restore(JList<?> list) {
    				list.setSelectedIndices(saved1);
    			}
    		}
     
    		Selection selection = new Selection();
    		list.addMouseListener(new MouseAdapter() {
     
    			public void mousePressed(MouseEvent e) {
    				selection.save(list, e);
    			}
     
    		});
     
    		for (int i = 0; i < adapters.length; i++) {
    			list.addMouseListener(adapters[i]);
    		}
     
    		list.addMouseListener(new MouseAdapter() {
     
    			public void mouseClicked(MouseEvent e) {
     
    				if (e.getClickCount() == 2 && !keyPressed(e) && !e.isPopupTrigger()) {
    					selection.restore(list); 
    					retour();
    				}
     
    			}
     
    			private boolean keyPressed(MouseEvent e) {
    				return e.isAltDown() || e.isShiftDown() || e.isAltDown() || e.isAltGraphDown() || e.isControlDown()
    						|| e.isMetaDown();
    			}
     
    		});
     
    		return list;
     
    	}
     
    	protected static void retour() {
    		JOptionPane.showMessageDialog(null, "retour() appelée");
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 265
    Points : 149
    Points
    149
    Par défaut
    Merci beaucoup Joel pour cette solution détaillée. Je vais l'essayer, mais je constate que ce n'est pas si simple que je le croyais
    Bonne journée
    Gégé

Discussions similaires

  1. [JSP]comment créer un listener pour ma base de données
    Par Ekimasu dans le forum Servlets/JSP
    Réponses: 14
    Dernier message: 10/05/2004, 14h49
  2. Listener sur un JPanel
    Par ptitelfe dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 27/03/2004, 13h14
  3. Fonction ord, mais où es tu ?
    Par Neilos dans le forum C++Builder
    Réponses: 6
    Dernier message: 30/12/2003, 21h56
  4. TNS:listener could not resolve SERVICE_NAME given in connect
    Par Sinclair dans le forum Administration
    Réponses: 15
    Dernier message: 20/08/2003, 17h26
  5. DoubleClick Listener & ENTER
    Par Pro_Fete dans le forum Composants
    Réponses: 4
    Dernier message: 27/01/2003, 13h23

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