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

JavaFX Discussion :

Task Multithread, modifier les enfants d'une HBox


Sujet :

JavaFX

  1. #1
    Membre régulier Avatar de Space23
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    185
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 185
    Points : 88
    Points
    88
    Par défaut Task Multithread, modifier les enfants d'une HBox
    Bonjour,

    Je m’essaye à l'utilisation des classes Task et Service de JavaFX pour le multithread mais j'avoue que je suis un peu perdu.

    Voici le scénario que je cherche à réaliser :
    1) Je clique sur un bouton de mon IHM.
    2) le click_handler lance un thread en parallèle (Task) qui réalise des calculs longs et complexes. Le thread JavaFX quant à lui se termine et me rend la main sur l'IHM.
    3) une fois le thread en parallèle terminé, il modifie les enfants d'une Hbox de mon IHM.

    Voici le code que j'ai mis en place.

    click_handler :
    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
    HBox hboxResultat = (HBox) vboxListInput .getChildren().get(indexHbox);
     
    Task<HBox> taskProcessWord = new Task<HBox>() {
     
        @Override
        protected HBox call() throws Exception {
            try {
                //Calculs longs et complexe.
            } catch (Exception e) {
                log.error(e);
            }
     
            //reinit hbox
            HBox myHbox = new HBox();
     
            //ajout nodes à ma hbox
            addInfosToHbox(myHbox);    
     
            return myHbox;
        }
    };
     
    hboxResultat = taskProcessWord.valueProperty().get();
    Thread th = new Thread(taskProcessWord);
    th.setDaemon(true);
    System.out.println("Starting background task...");
    th.start();
    Le code ci-dessus ne produit aucun résultat.

    Quelqu'un saurait-il m'indiquer comment résoudre ce problème ?

    Merci d'avance pour votre aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Bonjour,

    Tout ce qui est fait dans la méthode call() se déroule dans le Thread de la Task. Autant dire que si tu essaie de modifier un noeud qui est déjà attaché dans une scène, tu cours a la catastrophe. si on omet la première ligne dont je ne sais pas trop ce qu'elle fait la (vu que juste après tu écrase la valeur par celle crée par la tache), ici, tu crée un noeud et le modifie alors qu'il n'est pas attache a une scène, c'est bien !

    Ta Task est crée et exécutée par un Service, tu n'as pas a gérer un Thread a mano.

    Ton code devrai plutôt être comme ceci : ici le callback onSucceed est appelé durant le JavaFX Application Thread, si la tache s'est correctement terminée.

    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
     
    final Service<HBox> taskProcessService = new Service<HBox>() {
      @Override
      protected Task<HBox> createTask() {
         return new Task<HBox>() {
        @Override 
            protected HBox call() throws Exception {
            try {
                //Calculs longs et complexe.
            } catch (Exception e) {
                log.error(e);
            }
     
            //reinit hbox
            HBox myHbox = new HBox();
     
                    //ajout nodes à ma hbox
                    addInfosToHbox(myHbox);    
     
            return myHbox;
         }
           };   
         }
      }
    };
    taskProcessService.setOnSucceed(new EventHandler<WorkerStateEvent>() {
      @Override
      public void handle(WorkerStateEvent event) {
        HBox hboxResultat = taskProcessService.getValue(); 
        // Attacher ça dans la scène.
      }
    };
    taskProcessService.start();
    Si tu veux modifier des valeurs qui sont déjà dans la scène, il va falloir prendre un peu plus de précautions : pour éviter tout soucis, il faut faire la modif dans le JavaFX Application 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
     
    final HBox hboxResultat = (HBox) vboxListInput .getChildren().get(indexHbox);
    final Service<Void> taskProcessService = new Service<Void>() {
      @Override
      protected Task<Void> createTask() {
         return new Task<Void>() {
        @Override 
            protected Void call() throws Exception {
            try {
                //Calculs longs et complexe.
            } catch (Exception e) {
                log.error(e);
            }
                    // ajout nodes à ma hbox
                    // Comme la box est deja dans la scene, on met a jour son contenu dans le JavaFX Application Thread.
                    Platform.runLater(new Runnable() {
                       @Override
                       public void run() {
                          addInfosToHbox(hboxResultat, <ce qu'il faut pour mettre a jour le contenu>);
                       }
                    };    
     
            return null;
         }
           };   
         }
      }
    };
    taskProcessService.start();
    A noter que c'est bien beau de catcher et de loger l'exception dans la méthode call(), mais si elle ne remonte pas plus haut, il n'est pas possible de déterminer si la tache/le service est dans un état failed.
    Ca serait mieux de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    taskProcessService.setOnFailed(new EventHandler<WorkerStateEvent>() {
      @Override
      public void handle(WorkerStateEvent event) {
        log.error(taskProcessService.getException());
      }
    };
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. comment modifier les widgets dans une fenètre??
    Par afrikha dans le forum GTK+ avec C & C++
    Réponses: 6
    Dernier message: 14/10/2005, 14h48
  2. Réponses: 2
    Dernier message: 05/10/2005, 15h27
  3. comment modifier les données d'une table à travers un dbgrid
    Par bertrand_declerck dans le forum Bases de données
    Réponses: 12
    Dernier message: 19/07/2005, 09h51
  4. MySQL Administrator : modifier les données d'une table
    Par Robinounou dans le forum Outils
    Réponses: 4
    Dernier message: 13/07/2005, 17h21
  5. [EXCEL]Modifier les marges d'une page dans Excel
    Par ms91fr dans le forum Composants VCL
    Réponses: 4
    Dernier message: 06/01/2004, 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