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

SWT/JFace Java Discussion :

[SWT] Problème de perte de double clic


Sujet :

SWT/JFace Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 17
    Par défaut [SWT] Problème de perte de double clic
    Bonjour à tous,

    Avant toute chose, je suis dans un projet RCP sous eclipse 3.2 mais je n'ai pas posté dans le forum RCP car je pense que mon problème provient plus de SWT. Ne pas hésiter en cas de mauvais placement à le déplacer

    Voici mon cas :

    J'ai un tableau qui est écouté par deux événements :
    - Un selectionListener
    - Un MouseDoubleClick

    Mon selectionListener me permet de lancer des traitements. Et ces traitements doivent être lancés tout le temps même si l'on re-clic sur la même ligne.
    Mon MouseDoubleClick listener doit ouvrir une fenêtre.

    Les traitements lancés prennent un certain temps,donc nous avons mis un job de façon à spécifier à l'utilisateur que quelque chose se passe.

    Mon problème est le suivant :

    Quand je double clic sur une ligne du tableau, le selectionListener catch ma sélection et lance mes traitements (jusque là tout va bien) et donc lance mon job (c'est là qu'est le souci). En résultat mon événement mouseDoubleClick n'est pas catcher...

    J'ai donc chercher à comprendre se qui se passait et j'ai fait plusieurs tests :
    J'ai mis bêttement des system.out.println dans mes listener pour voir quand ils y passaient

    1. J'ai d'abord pensé que la perte de mon doubleClick était lié à la priorité des listeners, J'ai donc affecté à mon tableau mon événement doubleClick en premier et le selectionListener en deuxième : ceci n'a rien changé.
      On passe dans le selectionListener
      On ne passe pas dans le mouseDouvleClickListener
    2. J'ai ensuite pensé que la perte de mon doubleClick était lié au temps engendré par mes traitements. J'ai donc supprimé mon job et mis un Thread.sleep(10000) à la place dans le but de simuler le temps passé par mon job pour vérifier mon test. Là ma fenêtre s'est ouverte...
      On passe dans le selectionListener
      On passe dans le mouseDouvleClickListener
    3. J'ai donc commencé à chercher du côté de l'ouverture de mon job. J'ai donc mis à la place de mon job, un messageDialog classique. Là ma fenêtre ne s'est pas ouverte.
      On passe dans le selectionListener
      On ne passe pas dans le mouseDouvleClickListener
    4. Je me suis dit que la perte du double clic pouvait provenir de la perte de focus. Et donc j'ai intercepté en plus le FocusOut sur mon tableau et j'ai annulé c'est événement en gardant mon job. Là ma fenêtre ne s'est pas ouverte...
      On passe dans le selectionListener
      On ne passe pas dans le mouseDouvleClickListener


    Le problème provient donc de l'ouverture d'une fenêtre supplémentaire entraînant la perte de mon événement double clic...

    En attendant, on met un sablier à la place de la souris pour que ça passe...

    Est ce que quelqu'un aurait une idée pour contourner ce bug ?
    Merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 17
    Par défaut
    J'ai finalement trouvé la solution, il suffit de différer le lancement de mon selectionEvent via un thread et après de syncrhoniser l'ouverture de ma popup avec le thread.

    Voici le code correspondant :

    j'ai ma classe MyThread qui extend Thread :

    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
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    public class MyThreadDelay<E> extends Thread {
     
    	/**
             * The listener where event is delaied
             */
    	private Listener myListener;
    	/**
             * The event to delay
             */
    	private E myEvent;
    	/**
             * The method name to call on listener to reload the event
             */
    	private String handleEventName;
    	/**
             * The shell where popup will be shown : could be null
             */
    	private Shell myShell;
    	/**
             * The delay time in millisecond : default value is 100. 
             */
    	private Integer delay;
     
    	/**
             * @param myListener            : The listener where event is delaied (mandatory).
             * @param myEvent                       : The event to delay (mandatory).
             * @param handleEventName       : The name of method to call on listener to reload the event (mandatory).
             */
    	public MyThreadDelay(Listener myListener, E myEvent, String handleEventName) {
    		this(myListener,myEvent,handleEventName,null,100);
    	}
     
    	/**
             * @param myListener            : The listener where event is delaied (mandatory).
             * @param myEvent                       : The event to delay (mandatory).
             * @param handleEventName       : The name of method to call on listener to reload the event (mandatory).
             * @param myShell                       : The shell of popup that could launch in {@link #synchronize(Runnable)} method (non mandatory), could be null.
             */
    	public MyThreadDelay(Listener myListener, E myEvent, Shell myShell,String handleEventName) {
    		this(myListener,myEvent,handleEventName,myShell,100);
    	}
     
    	/**
             * @param myListener            : The listener where event is delaied (mandatory).
             * @param myEvent                       : The event to delay (mandatory).
             * @param handleEventName       : The name of method to call on listener to reload the event (mandatory).
             * @param delay                         : The delay time in millisecond : default value is 100.
             */
    	public MyThreadDelay(Listener myListener, E myEvent, String handleEventName, Integer delay) {
    		this(myListener,myEvent,handleEventName,null,delay);
    	}
    	/**
             * @param myListener            : The listener where event is delaied (mandatory).
             * @param myEvent                       : The event to delay (mandatory).
             * @param handleEventName       : The name of method to call on listener to reload the event (mandatory).
             * @param myShell                       : The shell of popup that could launch in {@link #synchronize(Runnable)} method (non mandatory), could be null.
             * @param delay                         : The delay time in millisecond : default value is 100.
             */
    	public MyThreadDelay(Listener myListener, E myEvent, String handleEventName, Shell myShell, Integer delay) {
    		super();
    		this.myListener = myListener;
    		this.myEvent = myEvent;
    		this.handleEventName = handleEventName;
    		this.delay = delay;
    		/*
    		 * If no shell was specify, then we used the main shell
    		 */
    		initMyShell(myShell);
     
    	}
     
    	/**
             * Init the shell with shell in paramters. If myShell is null, then the main shell will be used
             * @param myShell
             */
    	private void initMyShell(Shell myShell){
    		if (myShell == null)
    			if (PlatformUI.isWorkbenchRunning())
    				myShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
    		this.myShell = myShell;
    	}
     
    	/* (non-Javadoc)
    	 * @see java.lang.Thread#start()
    	 */
    	@Override
    	public synchronized void start() {
    		/*
    		 * We launch a sleep in order to delay the runs of event
    		 */
    		try {
    			Thread.sleep(delay);
     
    			/*
    			 * We reload the event on listener 
    			 */
    			ClassMethod.getResultMethod(myListener
    					, new Object[]{myEvent}
    			, handleEventName);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     
     
    	/**
             * Synchronize SWT process with the thread
             * @param runnable
             */
    	public void synchronize(Runnable runnable){
    		if (myShell == null)
    			initMyShell(null);
    		/*
    		 * We synchronize the thread with opens of popup
    		 */
    		myShell.getDisplay().syncExec(runnable);
    	}
     
    	/**
             * Asynchronize SWT process with the thread
             * @param runnable
             */
    	public void asynchronize(Runnable runnable){
    		if (myShell == null)
    			initMyShell(null);
    		/*
    		 * We synchronize the thread with opens of popup
    		 */
    		myShell.getDisplay().asyncExec(runnable);
    	}
     
     
    }
    Ensuite voici le code dans mon Listener pour pouvoir exécuter correctement les deux :
    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
     
    public class ListenerViewTestTable implements  
    	ISelectionChangedListener,
    	IDoubleClickListener
    {
     
    	/**
             * Used for non loop with MyThreadDelay
             */
    	private Boolean firstSelection = false;
    	/**
             * Used in order to know if double click event was catch
             */
    	private Boolean doubleClickExecute = false;
    	/**
             * An instance of MyThreadDelay
             */
    	private MyThreadDelay<SelectionChangedEvent> myThread;
     
    	/* (non-Javadoc)
    	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
    	 */
    	public void selectionChanged(SelectionChangedEvent event) {
    		/*
    		 * We intercept the run of selectionChangedEvent in order to let the double-click event to run
    		 * (Bug SWT witch loose double-click event when popup opens)
    		 * 
    		 * On intercept l'éxécution du selectionChangedEvent dans le but de laisser le double-clic event
    		 * se lancer (bug SWT qui perd l'événement double-clic quand une popup s'ouvre)
    		 */
     
    		if (!firstSelection){
    			firstSelection = true;
    			myThread = new MyThreadDelay<SelectionChangedEvent>(this
    					, event
    					,"selectionChanged");	
    			myThread.start();
    		}else{
    			/*
    			 * We reinit the value in order to manage loop
    			 * 
    			 * On réinitialise la valeur dans le but de ne pas avoir de boucle
    			 */
    			firstSelection = false;
    			/*
    			 * We avert the user
    			 */
    			if (doubleClickExecute){
    				doubleClickExecute = false;
    				myThread.asynchronize(new Runnable() {
     
    					public void run() {
    						MessageDialog.openInformation(
    								PlatformUI.getWorkbench().getActiveWorkbenchWindow().getDisplay(),
    								"Title Test",
    								"We could control event order");
    					}
     
    				});
    			}
     
    			/*
    			 * Each event have to be redirect in the listener.
    			 * No instructions have to be done there.
    			 * 
    			 * Chaque événement doit être redirigé dans le listener.
    			 * Aucune instruction ne doit être faite ici.
    			 */
    			... my tasks
    		}
     
     
    	}
     
    	/* (non-Javadoc)
    	 * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
    	 */
    	public void doubleClick(DoubleClickEvent event) {
    		doubleClickExecute = true;
    		/*
    		 * Each event have to be redirect in the listener.
    		 * No instructions have to be done there.
    		 * 
    		 * Chaque événement doit être redirigé dans le listener.
    		 * Aucune instruction ne doit être faite ici.
    		 */
    		...my tasks
     
    	}
     
    }
    du coup, le décalage laisse le temps à mon double clic de s'exécuter

    Voilà

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/06/2007, 10h05
  2. Réponses: 3
    Dernier message: 04/10/2005, 15h39
  3. Problème ouverture fichier par double clic...
    Par sankookai dans le forum MFC
    Réponses: 4
    Dernier message: 11/05/2005, 09h13
  4. [debutant][swt] CellEditor / CellModifier avec double clic
    Par antares24 dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 10/05/2005, 02h25
  5. [SWT] Problème de paramètre GridData
    Par yolepro dans le forum SWT/JFace
    Réponses: 4
    Dernier message: 06/12/2002, 10h37

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