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 :

JTable; Comment coder un listener pour accepter Double click et simple click


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 JTable; Comment coder un listener pour accepter Double click et simple click
    Bonjour,

    J'ai un problème pour gérer soit un simple click soit un double click sur une JTable.

    J'ai défini le listener suivant ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Table = new JTable();
    Table.addMouseListener(new MouseAdapter() 
    {
                 @Override
                public void mouseClicked(MouseEvent me) 
                {	
                     if (me.getClickCount() == 1)System.out.println("Simple click " );
                     else System.out.println("Double click "  );
    				}	 
    });
    Dans ce cas, même si je double clique rapidement, le Listener considère qu'il n'y a qu'un seul clic . Par contre deux clics successifs mais pas rapides, me permettent d'éditer la cellule.

    Maintenant, si je définis ma table comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Table = new JTable( 
    			{ 
    			private static final long serialVersionUID = 1L;
    			public boolean editCellAt(int row, int column, java.util.EventObject e) 
    	               {
    	                 return false;
    	              }
    		};
    alors, cette fois je peux différencier un double clics d'un simple clic, mais je ne peux plus éditer la cellule pour en changer le contenu.
    Dans un forum, j'ai vu que l'utilisation d'un Timer devrait me permettre d'y arriver, mais je n'arrive pas à m'en sortir.. Sans doute ai-je oublié quelque chose.

    Pourquoi fais-je ceci ?
    Dans le cas d'un double clic, je supprime la ligne, dans le cas d'un simple clic, je veux changer le contenu de la cellule.
    Pour l 'instant pour pallier le problème, j'ai ajouté une colonne que je renseigne si je veux supprimer la ligne, mais je n'aime pas beaucoup cette solution.

    Merci pour toutes suggestions. Mon code complet est ci-dessous.

    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
    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
     
    package test;
     
    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.BorderFactory;
    import javax.swing.JDialog;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.JTableHeader;
     
    public class Exemple extends JDialog
    {
    	private static final long serialVersionUID = 1L;
    	private	JTable 				Table				= null;
    	private DefaultTableModel   modelTable 			=  null; 
    	private JScrollPane 		scrollTable 		=  null; 
    	private javax.swing.JButton Terminer 			=  null; 
     
     
    	public Exemple()
    	{
    		super();
    		initialisation();
    	}
     
    	private void initialisation()() 
    	 {
    		setSize(585, 419);
    		getRootPane().setBorder( BorderFactory.createLineBorder(Color.RED) ); 	
    		javax.swing.JPanel ContentPane= new javax.swing.JPanel();
    		ContentPane.setName("ContentPane");
    		ContentPane.setLayout(null);
     
    		Terminer = new javax.swing.JButton();
    			Terminer.setName("Terminer");
    			Terminer.setText("Terminer");
    			Terminer.setBounds(199, 305, 91, 25);
    			Terminer.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){System.exit(0);}});
     
    		Table = new JTable();
    		/*
    		{ 
    			private static final long serialVersionUID = 1L;
    			public boolean editCellAt(int row, int column, java.util.EventObject e) 
    	         {
    	            return false;
    	         }
    		};
    		*/
    			Table.addMouseListener(new MouseAdapter() 
    			{
    				@Override
    				public void mouseClicked(MouseEvent me) 
    				{	
    					if (me.getClickCount() == 1)System.out.println("Simple click " );
    					else System.out.println("Double click "  );
    				}	 
    			});
     
    		scrollTable= 	new JScrollPane(); 
    			scrollTable.setViewportView(Table);
    			scrollTable.setBounds(40, 90, 472, 175);
    			scrollTable.setViewportView(Table);
     
    		ContentPane.setBackground(java.awt.Color.black);
    		ContentPane.add(Terminer, Terminer.getName());
    	  	ContentPane.add(scrollTable);
     
    		setContentPane(ContentPane);
    		execute();
    		this.setLocationRelativeTo(null);
    		this.setVisible(true);
    	 }
    	private void execute()
    	{
    		Object[] tableHeader = new Object[]{"mes valeurs"};
    		modelTable =  new DefaultTableModel(tableHeader, 0);
    	    modelTable.setRowCount(10);
    		modelTable.setColumnCount(1);
    		Table.setModel(modelTable);
    		JTableHeader header = Table.getTableHeader();
    		header.setBackground(java.awt.Color.yellow);
    		Table.setRowHeight(20);
    		Table.setShowGrid(true); 
    		for (int i=0;i<3 ; i++)  modelTable.insertRow(i, new Object[]{" Ligne " + i, });
    	}
    	public static void main(java.lang.String[] args) 
    	{ 
    		new Exemple( ).execute();;
     
    	}
    }

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

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 329
    Points : 443
    Points
    443
    Par défaut
    Personnellement, j'ajoutais un MouseListener avec 2 == e.getClickCount() et ça se passait très bien.
    Mais je ne surchargeait pas la JTable. Pour démarrer l'édition d'une cellule je gérais celà dans le modèle via isCellEditable(row, col):boolean.

  3. #3
    Membre émérite
    Homme Profil pro
    Ingénieur en génie logiciel
    Inscrit en
    Juin 2012
    Messages
    890
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur en génie logiciel
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2012
    Messages : 890
    Points : 2 526
    Points
    2 526
    Par défaut
    je faisais comme gervais.b

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       table.addMouseListener(new MouseAdapter() {
             public void mouseClicked(MouseEvent me) {
                if (me.getClickCount() == 2) {     //détecte double click
                   JTable target = (JTable)me.getSource();
                   int row = target.getSelectedRow(); 
                   int column = target.getSelectedColumn(); 
                  JOptionPane.showMessageDialog(null, table.getValueAt(row, column)); // affiche 
                }
             }
          });

  4. #4
    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
    Désolé, mais je n'ai pas bien compris.

    La question est bien de différencier un simple clic, d'un double clic. Or si je ne surcharge pas ma table, et reprends l'exemple de Marc, il renvoie toujours "simple clic". J'ai simplement ajouté l'affichage d'un message.

    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
     
    Table.addMouseListener(new MouseAdapter() {
    	         public void mouseClicked(MouseEvent me) 
    	         {
    	            if (me.getClickCount() == 2) {     //détecte double clic 
    	               JTable target = (JTable)me.getSource();
    	               int row = target.getSelectedRow(); 
    	               int column = target.getSelectedColumn(); 
    	               modelTable.isCellEditable(row, column);
    	               System.out.println("double clic"); // affiche 
    	              JOptionPane.showMessageDialog(null, Table.getValueAt(row, column)); // affiche 
    	            }
    	            if (me.getClickCount() == 1) {     //détecte simple clic 
    		              System.out.println("Simple clic"); // affiche 
    		            }
    	         }
    	      });
    Par contre ce que je n'ai pas compris, c'est comment utiliser la méthode isCellEditable pour différencier les deux types de clic. Un exemple serait le bienvenu.

    Quoi qu'il en soit je vous remercie tous les deux pour votre support.

    Gégé

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

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 329
    Points : 443
    Points
    443
    Par défaut
    Ok, je n'avais pas compris la subtilité de votre question. Le problème est que l'édition d'une cellule est démarrée par un double-click. Votre besoin d'éditer une cellule entre en conflit avec celui de détecter le double-click.

    Si votre table n'est pas éditable, alors le code que l'on vous donne fonctionne. Mais si elle est éditable, le code "natif" prend la main et intercepte le double-click.

  6. #6
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 96
    Points : 62
    Points
    62
    Par défaut
    Bonjour à tous.

    Je suis tombé sur ce vieux sujets et j'ai moi aussi galéré pour faire un listener capable de différencier un simple click d'un double click...

    J'ai fini par trouver une solution que voici ci-dessous:

    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
    import java.awt.Toolkit;
    import javax.swing.SwingUtilities;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
     
     
     
    public abstract class MouseClickListenerWithDoubleClickAction implements MouseListener {
    	private int clickCount;
    	private boolean waitingForSecondClick = false;
     
     
     
    	public abstract void onFirstClick(MouseEvent e);
    	public abstract void afterSingleClick(MouseEvent e);
    	public abstract void onSecondClick(MouseEvent e);
    	public abstract void afterDoubleClick(MouseEvent e);
     
     
     
     
    	public void mouseClicked(MouseEvent e) {
    		if(e.getClickCount() == 1) {
    			this.clickCount = 1;	
    			this.onFirstClick(e);
     
    			new Thread() {
    				public void run() {
    					MouseClickListenerWithDoubleClickAction.this.mouseFirstClick(e);
    				}
    			}.start();
    		}
    		else if(e.getClickCount() == 2) {
    			this.mouseDoubleClicked(e);
    		}
    	}
     
     
     
     
    	public synchronized void mouseFirstClick(MouseEvent e) {
    		try {
    			this.waitingForSecondClick = true;
    			this.wait(Integer.valueOf(Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval").toString()));
    			this.waitingForSecondClick = false;
    		}	
    		catch(InterruptedException ie) {
    			ie.printStackTrace();
    		}
     
    		try {
    			SwingUtilities.invokeAndWait(new Runnable() {
    				public void run() {
    					if(MouseClickListenerWithDoubleClickAction.this.clickCount == 1) {
    						MouseClickListenerWithDoubleClickAction.this.afterSingleClick(e);
    					}
    					else {
    						MouseClickListenerWithDoubleClickAction.this.afterDoubleClick(e);
    					}
    				}
    			});
    		}
    		catch(Exception ex) {
    			ex.printStackTrace();
    		}
    	}
     
    	public void mouseDoubleClicked(MouseEvent e) {
    		this.clickCount = 2;	
    		this.onSecondClick(e);
     
    		synchronized(this) {
    			if(this.waitingForSecondClick) this.notifyAll();
    		}					
    	}
    }
    il faut ajouter un objet de ma classe comme n'importe quel MouseListener, avec la méthode addMouseListener().

    Ce listener fonctionne comme suit:


    La méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract void onFirstClick(MouseEvent e);
    est appelée après un premier click, que le click soit simple ou double.

    La méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract void afterSingleClick(MouseEvent e);
    est appelée lorsque le click est simple.

    La méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract void onSecondClick(MouseEvent e);
    est appelée au deuxième click.

    La méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract void afterDoubleClick(MouseEvent e);
    est appelée après un double click.


    Vous n'avez qu'à surcharger ces quatre méthode à votre convenance.

    Notez que les deux dernières méthodes sont redondantes, mais j'ai fait le choix de mettre les deux pour plus de lisibilité.

    Chez moi ça marche plutôt bien, j'espère qu'il en sera de même pour vous.

Discussions similaires

  1. Comment créer un Listener pour une JList
    Par onh890 dans le forum Débuter
    Réponses: 2
    Dernier message: 18/05/2011, 23h46
  2. Réponses: 1
    Dernier message: 22/08/2009, 06h02
  3. événement JTable pour un double click
    Par hysah dans le forum Composants
    Réponses: 2
    Dernier message: 27/11/2008, 15h45
  4. Comment coder une tabulation pour cut ?
    Par ggnore dans le forum Linux
    Réponses: 2
    Dernier message: 26/11/2004, 10h31
  5. [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

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