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 :

Problème accès à un objet depuis un SwingWorker


Sujet :

EDT/SwingWorker Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : octobre 2011
    Messages : 45
    Points : 38
    Points
    38
    Par défaut Problème accès à un objet depuis un SwingWorker
    Bonjour,
    J'ai beaucoup de difficultées avec le SwingWorker.

    Dans ma classe SwingWorker, dans la méthode doInBackground()
    je crée un objet, je lui affecte des valeurs, mais le programme ne parvient pas à lire cet objet (alors qu'il est utilisé partout ailleurs sans problème).

    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
    public class SwCreateDoc extends SwingWorker<List<DocumentSas>, DocumentSas> implements ObsAbleAddDocJt{
     ...               
    public SwCreateDoc(List<?> input, Lot lot, JFrame parent, boolean bloc) {
    ...
                    }             
     
                    @Override
                    protected List<DocumentSas> doInBackground() throws Exception {
                    ...
                    DocumentSas doctmp = new DocumentSas();
                    doctmp.setIdLotParent(lotAtraiter.getIdLot());
                    doctmp.setNomDoc("DOC" + System.currentTimeMillis());
                    doctmp.setDateNumerisation(new Date());
                    doctmp.setFichierFile(f);
                    System.out.println(doctmp.toString());
                    // on cree un nouveau document en faisant appel au dao
                    doctmp = daoDoc.create(doctmp);
                    ...
                    }
    ...
    }
    dans l'exemple, en debug les set... fonctionnent, l'appel au dao ne fonctionne pas. J'ai ajouté un sysout afin de voir si je pouvais afficher les données de l'objet DocumentSas mais il ne s'affiche pas, le programme passe (comme pour l'appel au dao) dans une classe "FuturTask.class".
    le get() du SwingWorker lève une exception (que je ne comprend pas).

    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
                    at mim.ihm.traitements.TrtFenNumeris.importDocumentFs(TrtFenNumeris.java:79)
                    at mim.ihm.ihmNg.ControlPrincipNg.actionPerformed(ControlPrincipNg.java:376)
                    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
                    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
                    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
                    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
                    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
                    at java.awt.Component.processMouseEvent(Unknown Source)
                    at javax.swing.JComponent.processMouseEvent(Unknown Source)
                    at java.awt.Component.processEvent(Unknown Source)
                    at java.awt.Container.processEvent(Unknown Source)
                    at java.awt.Component.dispatchEventImpl(Unknown Source)
                    at java.awt.Container.dispatchEventImpl(Unknown Source)
                    at java.awt.Component.dispatchEvent(Unknown Source)
                    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
                    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
                    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
                    at java.awt.Container.dispatchEventImpl(Unknown Source)
                    at java.awt.Window.dispatchEventImpl(Unknown Source)
                    at java.awt.Component.dispatchEvent(Unknown Source)
                    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
                    at java.awt.EventQueue.access$200(Unknown Source)
                    at java.awt.EventQueue$3.run(Unknown Source)
                    at java.awt.EventQueue$3.run(Unknown Source)
                    at java.security.AccessController.doPrivileged(Native Method)
                    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
                    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
                    at java.awt.EventQueue$4.run(Unknown Source)
                    at java.awt.EventQueue$4.run(Unknown Source)
                    at java.security.AccessController.doPrivileged(Native Method)
                    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
                    at java.awt.EventQueue.dispatchEvent(Unknown Source)
                    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
                    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
                    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
                    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
                    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
                    at java.awt.EventDispatchThread.run(Unknown Source)
    Je n'arrive pas à trouver le problème. Un simple sysout qui n'affiche pas la valeur demandée alors qu'elle est disponible dans l'objet, comme si l’accès en lecture de cet objet était bloqué.
    Si quelqu'un a une idée...

    Merci.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Votre doInBackground() est censé renvoyer un List<DocumentSas>. S'il ne le fait pas ou que les exceptions sont mal gérées, alors le get() qui sera exécuté dans le done() du SwingWorker peut lever une exception (NullPointer, etc).

    Pour modifier un objet, passez le au constructeur du SwingWorker pour qu'il en garde une référence, et dans le done(), transmettez le résultat du doInBackGround() à cette référence initiale, par exemple.

    Un sysout dans le doInBackGround() est fait depuis un thread qui n'a pas accès à la console.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : octobre 2011
    Messages : 45
    Points : 38
    Points
    38
    Par défaut
    Merci,

    En fait les objets sont créés dans le SwingWorker qui retourne la liste des objets créés.

    Je viens de trouver la cause du problème, mais je ne parviens pas à l'expliquer.

    En cause la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    doctmp.setFichierFile(f);
    qui donne :
    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
    public void setFichierFile(File fichier) {
           this.fichierFile = fichier;
           setMiniature();
           hasChanged = true;
    }
     
    public void setMiniature() {
           Runnable th = new Runnable() {
                 public void run() {
                        Image im = PdFTools.getImageFromPdf(fichierFile.getAbsolutePath(), 0);
                        if (im.getWidth(null) > im.getHeight(null)) { // miniature paysage
                               miniature = new JLabel(new ImageIcon(im.getScaledInstance(120, 85, BufferedImage.TYPE_BYTE_BINARY)));
                        } else { // miniature portrait
                               miniature = new JLabel(new ImageIcon(im.getScaledInstance(85, 120, BufferedImage.TYPE_BYTE_BINARY)));
                        }
                        miniature.setPreferredSize(new Dimension(85, 120));
                 }
           };
           th.run();
           hasChanged = true;
    }
    Si je retire le Runnable cela fonctionne parfaitement.

    Dans mon projet, il y a pas mal de Runnable pour des traitements courts que je souhaite remplacer progressivement par des SwingWorkers. Je suis encore novice niveau Threads/SwingWorkers, et j'ai pas encore saisi tous les aspects du multithread.

    Pour ce qui est du get() mes exceptions sont clairement mal gérées car je na sais pas comment m'y prendre. Cela fera l'objet d'un autre post que j'ai déjà préparé mais pas validé.

    Merci.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    12 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 373
    Points : 29 307
    Points
    29 307
    Billets dans le blog
    2
    Par défaut
    Salut,

    L'exécution de la méthode run() du runnable dans setMiniature est faite dans le thread courant, donc celui du SwingWorker : lance ton programme en mode debug, puis quand ton programme gèle, utilise l'option du debugger de bloquage de l'exécution sur l'ensemble des threads, ce qui te permettra de voir les verrous entre les threads. Déjà, il n'est pas logique d'exécuter du code Swing dans le doInBackground du SwingWorker : le code Swing devrait être fait dans la méthode publish(). Mais peut-être est-ce PdFTools.getImageFromPdf(fichierFile.getAbsolutePath(), 0); qui est est en conflit.

    Autre chose : quel est le but de faire un Runnable dans setMiniature() ? Puisqu'on exécute run() dans le thread courant ? Ce que tu peux essayer (ce serait mieux de comprendre ce qu'il se passe pour savoir exactement ce qui est mal écrit, mais ça peut débloquer rapidement la situation), c'est un SwingUtilities.invokeLater(th) au lieu de th.run().
    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
    Nouveau membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : octobre 2011
    Messages : 45
    Points : 38
    Points
    38
    Par défaut
    Merci,

    J'ai voulu tester le SwingUtilities.invokeLater(th), mais le problème avait disparu.
    Le problème devait provenir d'autre part car cela refonctionne même avec le runnable (j'ai fait pas mal de nettoyage dans mon objet DocumentSas et ajouté des contrôles de valeurs null sur les méthodes set notamment).

    J'ai réécrit un nouveau SwingWorkers qui lui utilise le publish() que je vais tester de ce pas (et qui amène mon future post dans cette même section sur les remontée d'exceptions).

    Si j'ai bien compris, le runnable dans le setMiniature est inutile car il sera exécuté dans le thread du SwingWorker.

    Le problème est résolu même si je ne sais pas vraiment pourquoi.


    Merci de votre aide.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    12 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 373
    Points : 29 307
    Points
    29 307
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mrboliboli Voir le message
    Si j'ai bien compris, le runnable dans le setMiniature est inutile car il sera exécuté dans le thread du SwingWorker.
    Il est exécuté dans le thread courant (comme pour n'importe quel appel de méthode sur une instance) : ensuite, comme dans ton code c'est appelé depuis doInBackground du SwingWorker, oui, c'est exécuté dans le thread du SwingWorker pour cet appel là (mais ça peut être appelé de n'importe où à la limite)
    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
    Nouveau membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : octobre 2011
    Messages : 45
    Points : 38
    Points
    38
    Par défaut
    Ok c'est un peu plus clair comme cela.

    Merci.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/08/2012, 20h51
  2. [Débutant] problème accès classe C++ depuis projet C# WPF
    Par bebedemon dans le forum C#
    Réponses: 6
    Dernier message: 29/06/2011, 11h13
  3. Accés à un objet depuis un autre
    Par Aimar dans le forum VB.NET
    Réponses: 4
    Dernier message: 26/06/2009, 00h28
  4. Problème d'accès à un objet!
    Par chrono23 dans le forum C++
    Réponses: 21
    Dernier message: 26/06/2006, 21h21
  5. Réponses: 1
    Dernier message: 25/03/2006, 18h53

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