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

SWT/JFace Java Discussion :

Raffraichir l'UI pour éviter un freeze


Sujet :

SWT/JFace Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    1 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 190
    Par défaut Raffraichir l'UI pour éviter un freeze
    Bonjour!

    J'ai un problème que je n'arrive pas à résoudre, voici le contexte:
    J'ai une application RCP (avec SWT donc), qui sur un clic sur un bouton lance une tâche qui peut durer jusqu'à 1 minute.

    J'ai donc mis en place une fenêtre d'attente avec progress bar durant la durée de la tâche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     final IRunnableWithProgress op = new IRunnableWithProgress()
            {
              public void run(final IProgressMonitor monitor) throws InterruptedException,
                  InvocationTargetException
              {
                monitor.beginTask("Start tache", 0);
                ... traitement durant 1 minute ...
              }
            };
     
            final ProgressMonitorDialog d = new ProgressMonitorDialog(Display.getCurrent().getActiveShell());
     
            d.run(false, false, op);
    Le problème c'est que durant le traitement, je fais certaines chose qui font que je ne peux pas lancer le ProgressMonitorDialog dans un autre thread (avec d.run(true, true, op) ).

    Et donc si j'ai le malheur de faire un clic lorsque le ProgressMonitorDialog est ouvert, il se bloque le ThreadUI étant bloque par le traitement de la tâche:



    Et window me demande gentiment si je veux sauvagement fermer mon application puisqu'elle ne répond pas.

    Je voudrai donc savoir si j'ai un moyen de dé-freezer mon appli dans le code?
    J'ai essayé durant le traitement de faire des Thread.yield(), ou alors de lancer un autre Thread qui fait:
    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
     
            final ProgressMonitorDialog d = new ProgressMonitorDialog(Display.getCurrent().getActiveShell());
     
            new Thread() {
              public void run() {
                for (final int[] i = new int[1]; i[0] <= 9999999; i[0]++) {
                  try {
                    Thread.sleep(100);
                  } catch (Throwable th) {
                  }
                  if (display.isDisposed())
                    return;
                  display.asyncExec(new Runnable() {
                    public void run() {
                      d.getProgressMonitor().beginTask(i[0]+"", i[0]);
                     shell.redraw();
                    }
                  });
                }
              }
            }.start();
     
            d.run(false, false, op);
    Mais cela n'a aucun effet.

    Quelqu'un aurait une idée?
    Et je reprécise : je ne peux pas lancer le long traitement dans un autre Thread.

  2. #2
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    Salut,

    A mon avis, t'as un soucis de conception quelque part là...
    Si j'ai bien compris, tu cliques sur un bouton qui lance un traitement (relativement long), que tu ne peux pas lancer dans un Thread séparé de l'IHM. Déjà pourquoi? Parce que tu mets des composants graphiques à jour?
    Ensuite, est-ce que tu as vu les Job Eclipse?

    Voilà, à+
    Gueritarish

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    1 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 190
    Par défaut
    Oui il y a eu un grave souci de conception à la base. Durant le traitement, des shell et widgets sont crées/modifiés, et d'autre chose encore qui sont impossibles si je ne suis pas dans le ThreadUi.
    Et arranger cela prendrait malheureusement bien plus de temps que je n'en ai.

    C'est pourquoi je cherche juste quelque chose qui me permet de défreezer périodiquement ma fenêtre.

    J'avais déjà regarder les job notamment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            UIJob uiJob = new UIJob("Update UI")
            {
              public IStatus runInUIThread(IProgressMonitor monitor)
              {
                // traitement ...
                return Status.OK_STATUS;
              }
            };
            uiJob.schedule();
    Mais le problème est exactement le même, la fenetre freeze.

  4. #4
    Membre Expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Par défaut
    C'est plus que logique que la fenêtre freeze. Tu exécutes un code long dans le Thread UI. Tu veux pas non plus qu'il te fasse du café en même temps?
    S'il exécute un traitement, il ne peut pas mettre à jour la ProgressBar de la dialogue.
    Pour moi, il te faut passer par un travail sur la conception et utiliser un pattern Observer/Observable. Dans l'Observable tu vas envoyer des notifications chaque fois que tu souhaites mettre à jour un composant IHM (et seulement dans ces cas là).
    Après, une solution miracle existe peut-être, mais je la connais pas

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    1 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 190
    Par défaut
    Oui c'est bien logique que la fenêtre freeze, et j'attends justement une solution miracle , car hélas revenir sur la conception de l'appli n'est pas envisagé pour le moment.

    En fait, même la solution "laisser tel quel" est préféré à celle-ci donc bon...

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    je connais plus swing que swt, mais je comprend pas le problème, tu dois normalement faire ceci

    1) créer un thread séparé du ui
    2) faire le traitement de fond dans ce thread séparé
    3) quand un composant doit être modifier, instruire le thread UI de faire la modification (comme on le bloque pas il est libre)
    4) quand la modif est faite, poursuivre le traitement de fond.


    Avec swing, on utiliserait swingworker pour faire la 1) et SwingUtilities.invokeAndWait() pour faire le 3/4

    Je suis sur que swt doit avoir un truc équivalent

Discussions similaires

  1. [C#] Plusieurs Thread pour éviter le freeze du chargement
    Par mister3957 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 15/09/2006, 19h00
  2. Equivalence à Sleep pour éviter de figer l'application
    Par mickael.be dans le forum Langage
    Réponses: 3
    Dernier message: 29/12/2005, 04h23
  3. Formulation d'un UPDATE (pour éviter un curseur)
    Par GoLDoZ dans le forum Oracle
    Réponses: 2
    Dernier message: 15/11/2005, 16h35
  4. Réponses: 2
    Dernier message: 13/11/2005, 18h03

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