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 :

Question sur le TaskMonitor de la JSR 296


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    734
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 734
    Par défaut Question sur le TaskMonitor de la JSR 296
    Bonjour à tous,

    Je me penche en ce moment sur la JSR 296 pour voir si elle me suffit pour ma future application. Pendant mes tests, j'ai remarqué une curieux comportement sur le taskmonitor.

    Pour tester le comportement, créez une basic desktop application dans Netbeans 6.
    Rajouter une Task qui ne fait qu'un parcours dans une boucle de 1 à 100 avec une pause.

    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
     private class DoNothingTask extends Task {
     
            @Override
            protected Object doInBackground() throws Exception {
                for (int i = 0; i < 100; i++) {
                    System.out.println("de " + this.getTitle() + " valeur de i : " + i);
                    Thread.sleep(120L);
                    this.setProgress(i);
                }
                return null;
            }
     
            public DoNothingTask(Application arg0, int count) {
                super(arg0);
                this.setTitle("une Tache "+count);
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       private int count=0;
        @Action
        public Task launchTask() {
            count+=1;
            return new DoNothingTask(Application.getInstance(), count);
        }
    Dans le constructeur de la frameView rajoutez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
            taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
     
                public void propertyChange(PropertyChangeEvent evt) {
                    System.out.println("eventDispatch?"+SwingUtilities.isEventDispatchThread());
                    System.err.println("Evenment : "+evt.getPropertyName());
                }
            });
    Rajouter un bouton pour lancer la DonothingTask.

    Lancez l'application, cliquez plusieurs fois sur le bouton. Il y a donc autant de tâches qui sont lancées. Si vous regardez dans la sortie vous verrez que la méthode propertyChange n'est pas toujours appelé quand il le faut.

    Précision de la javadoc :
    This class is not thread-safe. All of its methods must be called on the event dispatching thread (EDT) and all of its listeners will run on the EDT.
    D'ailleurs la progresse bar et la busyicon ne changent plus dans ces moments là.

    Vu le comportement que j'observe, j'hésite à faire un rapport de bug.
    Qu'en pensez-vous? Est-ce que j'utilise mal la classe taskMonitor ou y a t'il un vrai problème?

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Tout d'abord, je crois que tu utilises mal la conception : la progressbar devrait idéalement afficher une seule tâche.

    Alors ce que je te conseille, c'est de
    1) te limiter à une tâche en même temps, c-à-d bloquer le bouton pour n'effectuer qu'une seule tâche (ou changer le bouton pour interrompre la tâche) ;
    2) ou créer une tâche-mère qui gèrera toutes les tâches enfants (chaque tâche enfant étant créée par un clic sur le bouton, et la tâche-mère étant créée lors du premier clic).

    Ensuite, pour quand même répondre à ton problème, vu que les listeners sont faits dans l'EDT, ET que donc tu effectues des Thread.sleep() dans l'EDT, tu bloques l'EDT, ce qui est extrêmement mauvais !

    Pour pallier à cela, tu dois créer un nouveau Thread dans ta méthode doInBackground(). Ce Thread fera alors exactement ce que tu désires, et débloquera ton EDT, ce qui raffraîchira ton application.

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    734
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 734
    Par défaut
    Citation Envoyé par dingoth Voir le message
    Tout d'abord, je crois que tu utilises mal la conception : la progressbar devrait idéalement afficher une seule tâche.

    Alors ce que je te conseille, c'est de
    1) te limiter à une tâche en même temps, c-à-d bloquer le bouton pour n'effectuer qu'une seule tâche (ou changer le bouton pour interrompre la tâche) ;
    2) ou créer une tâche-mère qui gèrera toutes les tâches enfants (chaque tâche enfant étant créée par un clic sur le bouton, et la tâche-mère étant créée lors du premier clic).

    Ensuite, pour quand même répondre à ton problème, vu que les listeners sont faits dans l'EDT, ET que donc tu effectues des Thread.sleep() dans l'EDT, tu bloques l'EDT, ce qui est extrêmement mauvais !

    Pour pallier à cela, tu dois créer un nouveau Thread dans ta méthode doInBackground(). Ce Thread fera alors exactement ce que tu désires, et débloquera ton EDT, ce qui raffraîchira ton application.
    Merci de ta réponse dingoth.

    La conception général n'est pas de moi et surtout la partie ajout de listener et de création de task, elle est issue d'un template de nebteans.(basic desktop application) qui utilise une nouveau framework swing qui sera intégré à terme dans java 7.

    L'ensemble fonctionne bien avec quelques threads.

    Normalement, il n'est pas nécessaire de créer un nouveau Thread dans doInBackgroups. La classe Task hérite de swingworker, cette partie s'exécute dans un thread séparé. Preuve en est, je peux cliquer autant de fois que je veux sur mon bouton pour lancer de nouveau thread, et le reste de mon IHM répond toujours bien.

    informations complémentaires

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Je connais bien le appframework, je l'utilise au quotidien. Mais ce que tu proposes est effectivement un cas particulier. Je me suis laissé emporter par le lundi matin dans ma réponse : tu ne fais effectivement pas le doInBackgrounds() dans l'EDT. Désolé.

    Je me réfère donc maintenant à SwingWorker : la méthode publish() appelée par setProgress() (de Task) crée un buffer d'objets à envoyer à process(). Elle peut donc avoir un comportement peu judicieux en bufferisant plusieurs setProgress() sans pour autant les répercuter (tant dans la JProgressBar que dans la console), malgré les 120ms d'attente pour chaque Thread.

    Pour la conception, je parle de ta manière de voir les choses. Typiquement, une barre de progression équivaut à une tâche. Dans le cas de plusieurs tâches, je crois qu'il faut être logique, et utiliser la barre de progression pour traiter l'avancement de l'ensemble des tâches et non une barre des tâches qui changerait de 90% à 10% puis à 45%, etc.

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    734
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 734
    Par défaut
    Oublions la barre de progression. Je reviendrais dessus lorsque j'aurais bien compris le taskmonitor.

    Ce dernier, si j'ai bien compris, permet de monitorer les tasks qui sont lancées.
    On peut donc écouter les changements d'état des tâches en cours d'exécution.
    et récupérer à tous moment l'ensemble des taches en cours.

    les listener reçoivent la notification de changement de la tâche qui est en train de travailler (la foregroundTask). Donc logiquement, je peux avoir un listener qui me sorte les changements d'état avec un println, mais voilà au bout de quelques taches, je ne reçoit plus aucune notification. Les tâches, elles continuent de fonctionner.

    C'est dernière partie là que je ne comprends pas. Avec 4 taches de lancée, pas de soucis au niveau du listener, au-delà je n'ai plus rien au bout de quelques minutes d'éxécution.

    Merci de m'éclairer de ta lanterne.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Copie/colle un peu le code intéressant de ton application de test, stp... C-à-d la classe étendant SingleFrameApplication : je n'ai pas NetBeans, mais Eclipse. Je n'ai donc pas le même template. Si tu as fais plusieurs fichiers, copie/colle les autres classes intéressantes.

Discussions similaires

  1. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 22h49
  2. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 22h23
  3. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 09h45
  4. Réponses: 2
    Dernier message: 11/08/2002, 22h27
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 17h11

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