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

Agents de placement/Fenêtres Java Discussion :

Swing thread EDT et JFrame


Sujet :

Agents de placement/Fenêtres Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut Swing thread EDT et JFrame
    Bonjour

    J’ai un problème de conception avec des Threads, l’EDT de swing et les Jframes.

    Je n’arrive pas a récupérer la JFrame (à externaliser ma fenêtre) pour relancer la création d’un nouveau Canvas avec les nouveaux graphes et à exécuter les Threads dans un ordre séquentiel (même avec executor).

    J’ai une première classe, BMS qui démarre les process Swing
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    createCanvas();
    createWindow(TITLE, canvas);
    Les traite et les stoppe. Puis 3 classes qui dérivent de celle-ci que je souhaite lancer en séquentiel (tache1 + tache2 + tache3 dans la même JFrame).

    J’ai essayé plusieurs variantes de launcher qui ne marchent pas pour le lancement séquentiel (toute fonctionne en parallèle)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        public static void main(String[] args) throws InterruptedException {
     
            FrameRunnable FR1= new FrameRunnable();
            FrameRunnable FR2= new FrameRunnable();
            FR1.start();
            FR1.join();
            FR2.start();
            FR2.join();
        }
    Ou (avec un bms implements Runnable)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        List<Runnable> runnables = new ArrayList<Runnable>();
                runnables.add(new FrameRunnable());
                runnables.add(new FrameRunnable());
                runnables.add(new FrameRunnable());
                runnables.add(new FrameRunnable());
                ExecutorService execute =     Executors.newSingleThreadExecutor();
                executeRunnables(execute, runnables);
        public static void executeRunnables(final ExecutorService service, List<Runnable> runnables){
                for(Runnable r : runnables){
                    service.execute(r);
                }
                service.shutdown();
            }
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public void actionPerformed(ActionEvent e) {
                new Thread(new Runnable() {
                    public void run() {
    …..
        SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
     
                        bms.start();
                        }
                       });
                    }
                }).start();
              }
    Quelqu'un saurait-il m'indiquer d’où vient le problème du séquentiel ? Du Thread EDT de Swing ? Des launchers ?
    Pour récupérer la JFrame sans la clôturer comment faire ça proprement ?

    Merci d'avance pour votre aide.

  2. #2
    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 : 56
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Je ne suis pas sur de comprendre quel est ton problème

    Tu n'arrives pas à exécuter 3 threads de manières séquentiels ?
    Ou tu n'arrives pas à leur passer une instance de frame ?
    Ou tu n'arrives pas à passer une instance de frame d'un thread vers le suivant ?

    Dans ton premier code, tu exécutes 2 instances de FrameRunnable que je suppose être des Threads, le second étant lancé lorsque le premier se termine.

    Dans le deuxième, tu "enfiles" 4 runnables (enfin 4 threads à priori que tu utilises comme Runnable) dans un singleThreadExecutor, donc ils devraient bien s'exécuter en séquence, l'un après l'autre. attention, toutefois, l'appel de shutdown empeche d'appeler ta méthode une seconde fois (il faut faire le shutdown lorsque tu n'a plus de tâches à éxécuter)

    Et dans le troisème, ton action déclenche un thread qui demande au thread swing d'exécuter sans bloquer ce thread de lancer un tâche effectué par la méthode start() de l'instance bms. le thread qui lance l'invokeLater ne sert pas à grand chose, puisqu'il ne fait rien d'autre que l'invokeLater qui n'est pas bloquant. quand à bms, est ce une instance de classe qui étend Thread ? Dans ce cas l'invokeLater imposte juste que ce thread soit démarré lorsque le thread swing se reveille, mais n'impose pas vraiment d'ordre dans l'éxécution de plusieurs threads


    Ce que je ne suis pas sur de comprendre c'est si tu cumules les trois codes, ou si ce sont des tests différents que tu as fait.

    Quoiqu'il en soit, si je résume, tu as une fenêtre, tu veux mettre à jour l'affichage de cette fenêtre, et pour ce faire, tu as besoin d'éxécuter 3 fois le même thread, mais en séquence, c'est ça ? que font ces threads, s'il faut les exécuter 3 fois ? pourquoi pas un thread unique qui lance trois tâches ?

    En ce qui concerne les traitements qui consiste à faire une tâche dans un thread qui n'est pas celui de swing et à mettre à jour avec le résultat de cette tâche un composant swing, tu peux utiliser un SwingWorker qui découpe chaque partie (le traitement parallèle, la collecte des résultat, la mise à jour de l'affichage...) dans des méthodes séparées bien identifiées, qui simplifie la mise en oeuvre

    Lancer plusieurs Runnable en séquence, s'effectue simplement avec un SingleThreadExecutor, ou alors chaque runnable est chargé de lancer le suivant à la fin de la méthode run(), ce qui impose il est vrai d'avoir une référence sur le suivant
    lancer plusieurs SwingWorker les uns après les autres, revient un peut être à la même chose (on peut faire un Runnable, qui exécute un SwingWorker, mais je pense que ce serait plus simple d'avoir un SwingWorker unique qui chainent les différentes tâches... on les passerait par exemple en argument du constructeur du swingworker.

    Ce qui n'est pas très clair également pour moi c'est si tes tâches doivent mettre à jour différentes fenêtres ou toujours la même ?

    Si ce n'est pas la même, il faudrait que le résultat d'une tâche envoyée à la méthode publish du swingworker ait la référence de la fenêtre à mettre à jour.
    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.

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Tu n'arrives pas à exécuter 3 threads de manières séquentiels ?
    Ou tu n'arrives pas à leur passer une instance de frame ?
    Ou tu n'arrives pas à passer une instance de frame d'un thread vers le suivant ?
    C'est ça j'ai 2 problèmes : je veux 3 threads à exécuter de façon séquentielle (en enchainant les 3 dans la même frame) et donner la référence de ma frame pour reconstruire le canvas (les classes font une animation graphique différente)
    Citation Envoyé par joel.drigo Voir le message
    Dans ton premier code, tu exécutes 2 instances de FrameRunnable que je suppose être des Threads, le second étant lancé lorsque le premier se termine.

    Dans le deuxième, tu "enfiles" 4 runnables (enfin 4 threads a priori que tu utilises comme Runnable) dans un singleThreadExecutor, donc ils devraient bien s'exécuter en séquence, l'un après l'autre. Attention toutefois, l'appel de shutdown empêche d'appeler ta méthode une seconde fois (il faut faire le shutdown lorsque tu n'a plus de tâches à exécuter).

    Et dans le troisième, ton action déclenche un thread qui demande au thread swing d'exécuter sans bloquer ce thread de lancer un tâche effectué par la méthode start() de l'instance bms. le thread qui lance l'invokeLater ne sert pas à grand chose, puisqu'il ne fait rien d'autre que l'invokeLater qui n'est pas bloquant. Quand à bms, est-ce une instance de classe qui étend Thread ? Dans ce cas l'invokeLater imposte juste que ce thread soit démarré lorsque le thread swing se réveille mais n'impose pas vraiment d'ordre dans l’exécution de plusieurs threads
    Ce sont les 3 essais que j'ai tentés : ce sont des tests différents !
    Citation Envoyé par joel.drigo Voir le message
    Ce que je ne suis pas sur de comprendre c'est si tu cumules les trois codes, ou si ce sont des tests différents que tu as fait.

    Quoi qu'il en soit, si je résume, tu as une fenêtre, tu veux mettre à jour l'affichage de cette fenêtre, et pour ce faire, tu as besoin d’exécuter 3 fois le même thread mais en séquence, c'est ça ? Que font ces threads, s'il faut les exécuter 3 fois ? Pourquoi pas un thread unique qui lance trois tâches ?
    C'est exactement ça ... pourquoi pas un seul Thread ? Ben je pensais que c'etait plus simple d'en avoir 3 séparés (pour renvoyer les résultats et ne pas trop toucher les classes d'animation)
    Citation Envoyé par joel.drigo Voir le message
    En ce qui concerne les traitements qui consistent à faire une tâche dans un thread qui n'est pas celui de Swing et à mettre à jour avec le résultat de cette tâche un composant Swing, tu peux utiliser un SwingWorker qui découpe chaque partie (le traitement parallèle, la collecte des résultats, la mise à jour de l'affichage...) dans des méthodes séparées bien identifiées, qui simplifie la mise en oeuvre.
    Je n'ai pas encore essayé le SwingWorker
    Citation Envoyé par joel.drigo Voir le message
    Lancer plusieurs Runnable en séquence, s'effectue simplement avec un SingleThreadExecutor, ou alors chaque runnable est chargé de lancer le suivant à la fin de la méthode run(), ce qui impose il est vrai d'avoir une référence sur le suivant.
    Lancer plusieurs SwingWorker les uns après les autres, revient peut être à la même chose (on peut faire un Runnable, qui exécute un SwingWorker, mais je pense que ce serait plus simple d'avoir un SwingWorker unique qui chainent les différentes tâches... on les passerait par exemple en argument du constructeur du SwingWorker.
    SingleThreadExecutor ne marche pas dans mon cas.
    Citation Envoyé par joel.drigo Voir le message
    Ce qui n'est pas très clair également pour moi c'est si tes tâches doivent mettre à jour différentes fenêtres ou toujours la même ?
    Toujours la même frame.
    Citation Envoyé par joel.drigo Voir le message
    Si ce n'est pas la même, il faudrait que le résultat d'une tâche envoyée à la méthode publish du SwingWorker ait la référence de la fenêtre à mettre à jour.
    Pourrais-tu me décrire une solution qui :
    - dans une même frame
    - exécute en séquentiel une "animation" dans un canvas (le canvas étant redéfini chaque fois) : passer l’état "fin" de ma première animation à la 2nde.
    J'obtiens les 3 animations en même temps dans 3 frames différentes.

    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 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Donc si j'ai bien compris, tu veux afficher à la suite trois animations différentes, dans une même frame, en créant un nouveau canvas pour chacune des animations.

    Je t'ai fais ça (voir pièce jointe), vite fait à l'arrache à base d'un thread : si ce que tu cherches à faire, tu as un exemple. N'hésite pas à me demander des explications si nécessaire...
    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 actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut star et etoile
    thanks pour le code.
    Mon probleme de jframe est résolu.
    Me reste juste a terminer proprement mon anim java3D sans killer la fenetre et tout devrait marcher correctement.
    La solution d'un seul Thread était la bonne !

  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 : 56
    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
    Billets dans le blog
    2
    Par défaut
    Voici la version avec doublebuffering et l'ajout de la possibilité d'arrêter une animation (clic sur le canvas).

    Pour traiter le cas de lancement de benchmark, je procéderais de la manière suivante :
    - ajout une méthode startBenchmark() qui fait
    1 - il initialise les mesures
    2 - animateCanvas()
    3 - il collecte les résultats de mesures
    - au lieu de doAnimation(), tu fais une méthode doBenchMarkStep() du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private void doBenchmarkStep() {
        doAnimation();
        storeResults();
    }
    storeResults() peut lancer une tache éxécutée par un ExecutorService pour ne pas trop géner l'animation et à la fin du stockage, tu peux
    éventuellement lancer un évenement
    - ta frame principale écoute ces évenements, et dans l'écouteur, fait un invokeLater pour les afficher dans un autre panel de ta fraime, (ou collecte tous tes résultats à la fin de toutes les animes pour les afficher en une fois)
    Fichiers attachés Fichiers attachés
    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. [Swing][Thread] Authentifier proprement un utilisateur
    Par Invité dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 15/09/2006, 13h37
  2. Réponses: 11
    Dernier message: 04/08/2006, 12h07
  3. Outils swing marche pas dans JFrame
    Par pat-trix dans le forum Agents de placement/Fenêtres
    Réponses: 7
    Dernier message: 27/06/2006, 20h32
  4. [SWING]Dimensions d'une JFrame
    Par lionrouge dans le forum Agents de placement/Fenêtres
    Réponses: 16
    Dernier message: 20/06/2006, 01h13
  5. [SWING][THREAD]Méthodes pour afficher une Frame
    Par pompidouwa dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 05/05/2004, 11h35

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