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

Interfaces Graphiques en Java Discussion :

Listener pour un point


Sujet :

Interfaces Graphiques en Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut Listener pour un point
    Bonsoir,

    Je travaille actuellement sur une interface graphique pour un gros projet.
    L'utilisateur pourra interagir avec l'interface grâce à ses mouvements (il y a une kinect dans le projet)

    Un sous programme permet de donner la position de la main de l'utilisateur.

    J'aimerais faire un listener pour la main qui permettrait de détecter si la main reste 3 seconde dans une certaine zone.
    Les tutos que je vois sur internet pour creer des listener reposent tous sur des listeners deja existant. Là je n'ai pas vraiment d'idée.

    Une idée ?

    Merci beaucoup

  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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Ta question concerne la mise en œuvre d'un "listener" en général, en en particulier pour kinect ?

    Pour le cas général, on procède simplement comme suit :

    • On fait une interface qui constitue le listener
      • le mieux est de faire une interface (personnellement, je préfère toujours faire une interface fonctionnelle, à une méthode donc, ce qui permet d'utiliser les lambdas pour l'implémentation de l'écouteur), qui permettra de réagir aux évenements
      • On peut soit
        • avoir en argument les informations qui permettent de savoir qui à produit le changement d'état, la valeur de l'état, l'ancienne valeur de l'état éventuellement, etc.
        • Mieux, faire une classe qui réprésente l'évenement, et y mettre les informations nécessaires (ce qui permet de faire évoluer plus facilement le code sans impact, et qui plus simple à écrire/lire
    • Dans la classe qui produit les changements d'états
      • On fait une méthode pour enregistrer un écouteur
        • Dans le cas général, on stocke les listeners dans une List<interface de listener>
      • On fait une méthode qui permet de retirer un écouteur d'évenement
      • Une méthode qui permet de lancer l'évenement
        • On parcourt les listeners et on invoque la méthode
        • Eventuellement, on prévoit une exécution thread-safe (qui permet d'ajouter ou supprimer un listener, et de lancer l'évenement, dans différents threads concurrents, mais ce n'est pas forcément indispensable
        • Il peut être avantageux de prévoir une gestion d'exception par handler externe (UncaughtExceptionHandler) afin d'éviter une rupture de l'envoi des évenements à plusieurs listeners, si l'un d'eux produisait des exceptions.


    Voici un exemple, avec une classe qui contient un état, dont on veut écouter les changements de valeurs :

    La classe qui représente l'évenement :
    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
    public class MonEvenement {
     
    	private final Object source;
    	private final int ancienEtat;
    	private final int nouvelEtat;
     
    	public MonEvenement(Object source, int ancienEtat, int nouvelEtat) {
    		this.source=source;
    		this.ancienEtat=ancienEtat;
    		this.nouvelEtat=nouvelEtat;
    	}
     
    	public final Object getSource() {
    		return source;
    	}
     
    	public final int getAncienEtat() {
    		return ancienEtat;
    	}
     
    	public final int getNouvelEtat() {
    		return nouvelEtat;
    	}
     
    }
    L'interface pour l'écouteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @FunctionalInterface
    public interface IMonListener {
     
    	void changementEtat(MonEvenement evenement);
     
    }
    La classe qui produit le changement d'état (en mode synchrone, pour de l'asynchrone, on peut utiliser un Executor pour traiter le fireEvent):
    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
    public class MonProducteurDEvenements {
     
    	private final List<IMonListener> monEvenementlisteners;
     
    	private int etat;
     
    	public MonProducteurDEvenements() {
    		monEvenementlisteners = new ArrayList<>();
    	}
     
    	public void setEtat(int nouvelEtat) {
    		int ancientEtat = this.etat;
    		this.etat=nouvelEtat;
    		fireEvent(ancientEtat, nouvelEtat); // on lance l'événement qui indique que l'état a changé
    	}
     
    	public int getEtat() {
    		return etat;
    	}
     
            // enregistrement écouteur
    	public void ajouterMonListener(IMonListener listener) {
    		Objects.requireNonNull(listener, "un listener ne doit pas être null");
    		synchronized (monEvenementlisteners) {
    		    if ( monEvenementlisteners.contains(listener) ) {
    		    	monEvenementlisteners.add(listener);
    		    }
    		}
    	}
     
            // arrêt de l'écoute
    	public void retirerMonListener(IMonListener listener) {
    		synchronized (monEvenementlisteners) {
    		    monEvenementlisteners.remove(listener);
    		}
    	}
     
            // envoi de l'événement aux écouteurs
    	private void fireEvent(int ancienEtat, int nouvelEtat) {
    		MonEvenement evenement = new MonEvenement(this, ancienEtat, nouvelEtat);
    		synchronized (monEvenementlisteners) {
    			for( IMonListener listener : monEvenementlisteners ) {
    				listener.changementEtat(evenement);
    			}
    		}
    	}
     
    }
    Dans ton cas, je suppose que la kinect produit elle-même des événements : tu peux sur écoute de ces évenements, générer d'autres évenements qui spécialisent l'action résultant. Pour la durée de 3 secondes, je ne sais pas comment ces évenements sont écoutables dans l'API de la kinect : si ce n'est pas prévu nativement, il te faudra chronométrer toi-même. Tu peux éventuellement utiliser un Timer pour ça : à la réception l'évenement kinect qui correspond à la détection de la main, tu lances une TimerTask avec un délai de 3 secondes, qui lance le fireEvent. Quand tu reçois l'évenement qui dit que la détection de la main n'est plus active, tu annules la timertask.
    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 averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut
    Merci beaucoup
    Ca m'a quand même l'air pas mal compliqué.
    Je regarde tout ça et je vous tient au courant
    Encore merci !

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut
    J'ai bien regardé votre code. Je l'ai compris.

    Ce qui genere l'évênement en gros c'est la méthode setEtat.

    Le problème que je me pose c'est comment utiliser ce code. Il existera une méthode getPosition qui renvoie la position de la main.

    Faut il alors faire quelque chose du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while(true){
    if(mainDansLaZone(getPosition()))
       setEtat(...)
    }
     
    // la méthode mainDansLaZone renvoie un bouléan qui est vrai si la position de la main est dans la zone voulue.
    Cette boucle infinie ne m'inspire pas grand chose. C'est bien ce qu'il faut faire ?

  5. #5
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    C'était juste un exemple général : le problème c'est que je ne sais pas comment est faite ton API Kinect, donc je peux difficilement de donner des indications plus spécifiques. C'est quoi déjà comme API ? J4K ?
    C'est quoi mainDansLaZone() ? C'est une méthode à toi ? Quel est son code ? Ne repose-t-elle pas sur un système évènementiel ? Ce serait préférable à une boucle while(true) qui va consommer du cpu à rien faire qu'attendre...

    Moi, je vois un système avec 2 évènements :
    • main dans la zone
    • main hors de la zone


    Et faire :
    • Quand "main dans la zone", lancer timer, delai 3 secondes
    • Quand "main hors de la zone", annuler timer
    • quand timer se déclenche, lancer évenement "main dans la zone pendant 3 secondes)
    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.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut
    Merci pour la réponse

    pour la méthode mainDansLaZone() c'est codé comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public boolean mainDansLaZone(Point p){
         return(p.getX()<maxX && p.getX()>minX && p.getY()<maxY && p.getY()> minY)
    }
    sachant que la zone dont on parle est un rectangle compris entre minX et maxX pour x et minY et maxY pour y

    dans le programme j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mainDansLaZone(getPosition()) // sachant que getPosition donne un Point (les coo de la main)
    Pour la kinect je ne sais pas quelle API est utilisée (ce n'est pas ma partie). Le problème étant que le sous programme Kinect est codé en C++ (on utilise des Pipes pour communiquer entre le java et la C++)

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

Discussions similaires

  1. [3D] matrice de déformation pour un point de vue décalé
    Par mou013 dans le forum Développement 2D, 3D et Jeux
    Réponses: 3
    Dernier message: 04/02/2006, 18h29
  2. [Débutant] Listener pour une entrée dans le presse papier.
    Par Silvio02 dans le forum Général Java
    Réponses: 6
    Dernier message: 08/01/2006, 22h44
  3. Quel listener pour l'édition d'une JTable?
    Par ®om dans le forum Composants
    Réponses: 4
    Dernier message: 11/05/2005, 21h13
  4. [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