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

EDT/SwingWorker Java Discussion :

Bloquer swingworker en attendant une saisie utilisateur dans un Jdialog et comment la récupérer ?


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre à l'essai
    Inscrit en
    Septembre 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 28
    Points : 13
    Points
    13
    Par défaut Bloquer swingworker en attendant une saisie utilisateur dans un Jdialog et comment la récupérer ?
    Bonjour à tous,

    Comment bloquer un swingworker tant qu’un utilisateur n’a pas saisi et validé dans un Jdialog une information ? Je m’explique.

    Je dois lancer un traitement qui prend du temps à partir d’une IHM Swing. Ce traitement réalise divers calculs et à la fin doit stocker le résultat dans un fichier qui sera écrit sur le disque.

    Le nom du fichier qui contiendra le résultat est choisi par l’utilisateur dans un Jdialog.
    Comme mon traitement est long, je veux profiter du temps que prendra l’utilisateur à rentrer dans le Jdialog le nom du fichier, et lancer en parrallèle le SwingWorker.

    Mes questions :

    • Comment bloquer le SwingWorker si l’utilisateur n’a pas encore saisi et validé le nom du fichier à utiliser au moment d'écrire le résultat ?
    • Comment récupérer le nom que l’utilisateur aura saisi ?


    J’ai bien pensé à utiliser un CountDownLatch dans MySwingWorker, mais dans ce cas je ne peux pas récupérer la valeur de filename.

    Autre possibilité : utiliser une BlockingQueue, mais j’ai l’impression d’utiliser un marteau-pilon pour écraser une mouche, car il faudrait que je gère également l’envoi d’un fileName bidon pour terminer le traitement et fermer la queue.

    Avez-vous une solution simple et efficace (j’utilise Java SE7) ?

    Voici ci-dessous le squelette de code :

    Le code de lancement à partir de mon IHM Swing :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        	protected void someButtonActionPerformed(ActionEvent e) {
                MySwingWoker woker = new MySwingWorker();
                Worker.execute;
                String fileName = JOptionPane.showInputDialog(this,
    				"Enter the name of the file");
            }
    et le code de MySwingWorker:

    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 MyWorker extends SwingWorker<Void, Void> {
     
    …
     
        @Override
        protected void doInBackground() throws Exception {
            doSomeBigComputation();
            WriteResultInFile();
        }
     
        protected void WriteResultInFile() {
     
            // Comment attendre ici ?	
            Path p = Paths.get(fileName);
            // Comment récupérer la valeur de fileName de manière propre ?
            try {
                Files.createFile(p);
            } catch (FileAlreadyExistsException e) {
                Logger.getLogger(HMyWorker.class.getName()).log(Level.WARNING, null, e);
            } catch (IOException e) {
                Logger.getLogger(MyWorker.class.getName()).log(Level.WARNING, null, e);
            }
        }
    }

  2. #2
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Autant demander à l'utilisateur de saisir le nom du fichier avant de lancer le SwingWorker. Le gain en temps sera vraiment minimal pour complexifier à ce point ton code.

    C'est le genre de truc que l'on met dans la catégorie optimisation non nécessaire, tu ferais mieux de voir si tu n'as pas moyen d'optimiser le traitement en lui même.
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  3. #3
    Membre à l'essai
    Inscrit en
    Septembre 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 28
    Points : 13
    Points
    13
    Par défaut
    Ok promis, j'optimiserai le code de ma tâche longue
    Mais elle sera vraiment longue et donc je me dis que j'ai tout intérêt à profiter de l'inertie/lenteur de l'utilisateur.
    De plus la question m'intéresse d'un point de vue théorique.
    Donc, j'ai hate de lire vos propositions

  4. #4
    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 : 54
    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 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    moi je mettrai juste une variable file dans MySwingWorker, avec une méthode pour le passer sa valeur appelée après la saisie, et le tester à la fin de ton process long, dans une boucle while, pour attendre qu'il passe à !=null.

    de la même façon que tu vas appeler cancel sur ton worker si l'utilisateur clique annuler lors de la sélection du fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( file==null ) {
        // annulation
        myswingworker.cancel(true);
    } else {
        myswingworker.setTargetFile(file);
    }
    et à la fin de ton traitement long, juste avant d'exploiter ton fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(file!=null && !isCancelled()) yield();
    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.

  5. #5
    Membre à l'essai
    Inscrit en
    Septembre 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 28
    Points : 13
    Points
    13
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Salut,

    moi je mettrai juste une variable file dans MySwingWorker, avec une méthode pour le passer sa valeur appelée après la saisie, et le tester à la fin de ton process long, dans une boucle while, pour attendre qu'il passe à !=null.

    de la même façon que tu vas appeler cancel sur ton worker si l'utilisateur clique annuler lors de la sélection du fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( file==null ) {
        // annulation
        myswingworker.cancel(true);
    } else {
        myswingworker.setTargetFile(file);
    }
    et à la fin de ton traitement long, juste avant d'exploiter ton fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(file!=null && !isCancelled()) yield();
    Ca revient à utiliser un CountDownLatch non ?

  6. #6
    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 : 54
    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 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    oui, un CountDownLatch avec une valeur de compteur à 1, mais il faut quand même avoir une variable file en plus. La boucle d'attente sera probablement mieux gérée (plus proprement du moins) qu'avec un while (on pourrait utiliser des wait() et notify() aussi pour éviter de consommer du cpu à faire un while).
    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.

  7. #7
    Membre à l'essai
    Inscrit en
    Septembre 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 28
    Points : 13
    Points
    13
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    oui, un CountDownLatch avec une valeur de compteur à 1, mais il faut quand même avoir une variable file en plus. La boucle d'attente sera probablement mieux gérée (plus proprement du moins) qu'avec un while (on pourrait utiliser des wait() et notify() aussi pour éviter de consommer du cpu à faire un while).
    Pour la variable filename, on peut faire comme tu as dit et ensuite on décrémente le compteur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        protected void someButtonActionPerformed(ActionEvent e) {
            CountDownLatch latch = new CountDownLatch(1);
            MySwingWorker worker = new MySwingWorker<>(latch);
            worker.execute;
            String fileName = JOptionPane.showInputDialog(this,
                                "Enter the name of the file");
            worker.setTargetFile(fileName);
            latch.countDown();
        }
    ça doit marcher, non ?

  8. #8
    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 : 54
    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 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    oui ça marche comme ça, et je n'ai pas dit le contraire,

    donc pour une solution claire pour tous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    protected void someButtonActionPerformed(ActionEvent e) {
               MySwingWoker worker = new MySwingWorker();
                worker.execute();
                String fileName = JOptionPane.showInputDialog(this,
    				"Enter the name of the file");
                worker.setTargetFile(fileName);
    }
    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
     
    public class MySwingWorker extends SwingWorker<Void, Void> {
     
         private String filename;
         private CountDownLatch latch;
    
    
         public MySwingWorker() {
             latch=new CountDownLatch(1);
         }
    
         public void setTargetFile(String filename) {
    
              this.filename=filename;
              latch.countDown();
              if ( filename==null ) {
                 cancel(true);
              }
         }
    
    …
     
        @Override
        protected void doInBackground() throws Exception {
            doSomeBigComputation();
            WriteResultInFile();
        }
     
        protected void WriteResultInFile() {
     
            latch.await();
    
            if ( filename==null ) {
                // annulation
                return;
            }
    
            // Comment attendre ici ?	
            Path p = Paths.get(fileName);
            // Comment récupérer la valeur de fileName de manière propre ?
            try {
                Files.createFile(p);
            } catch (FileAlreadyExistsException e) {
                Logger.getLogger(HMyWorker.class.getName()).log(Level.WARNING, null, e);
            } catch (IOException e) {
                Logger.getLogger(MyWorker.class.getName()).log(Level.WARNING, null, 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.

Discussions similaires

  1. Réponses: 3
    Dernier message: 17/02/2015, 15h34
  2. [batch] récupérer une saisie utilisateur
    Par yelbied dans le forum Windows
    Réponses: 5
    Dernier message: 28/08/2007, 15h34
  3. Réponses: 4
    Dernier message: 23/02/2007, 09h37
  4. [C#] Vérification de la saisie utilisateur dans un DataGridView
    Par Jinroh77 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 20/09/2006, 09h36
  5. rendre une saisie obligatoire dans un formulaire
    Par heteroclite dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 17/09/2006, 23h26

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