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 :

[Thread] Blocage dans mon programme


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 34
    Points : 23
    Points
    23
    Par défaut [Thread] Blocage dans mon programme
    Bonjour, donc voici mon code Chronos.java :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
     
     
    public class Chronos extends JFrame implements ActionListener {
    static int nbOnglets;
    public JTabbedPane lesChronos = new JTabbedPane();
    JPanel mainPanel = new JPanel();
    JButton ajChrono = new JButton("Nouvel Onglet");
     
    public  Chronos() {
    super("JavaChronos");
    setSize(500, 400);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    ajChrono.addActionListener(this);
    mainPanel.add(ajChrono);
    lesChronos.addTab("Main", mainPanel);
     
     
    getContentPane().add(lesChronos);
    setVisible(true);
    }
     
    public static void main(String[] arguments) {
    new Chronos();
    }
     
    public void actionPerformed(ActionEvent event) {
    AjoutChrono();
    }
     
    public void AjoutChrono() {
    TimePanel newChrono = new TimePanel();
    lesChronos.addTab("Onglet n° "+nbOnglets, newChrono);
    nbOnglets++;
     
    }
    }
     
     
     
     
     
    class TimePanel extends JPanel implements ActionListener {
    JLabel temps = new JLabel("00:00:00");
    int h, m, s;
    boolean started; 
    JButton start = new JButton("Start !");
    JButton stop = new JButton("Stop !");
    JButton raz = new JButton("RAZ");
     
    public TimePanel() {
    super();
    this.started=true;
    add(temps);
    add(start);
    add(stop);
    add(raz);
    start.addActionListener(this);
    stop.addActionListener(this);
    raz.addActionListener(this);
     
     try{  
     Thread.sleep(1000);
     
     } 
    catch(InterruptedException ie) {
     
    } 
     
    Timer();
     
    }
     
    public void actionPerformed(ActionEvent event) {
    Object source = event.getSource() ;
    if(source==start) {this.started=true; }
    if(source==stop) {this.started=false; }
    if(source==raz) {
    int reponse = JOptionPane.showConfirmDialog(this, "Etes-vous sûr de vouloir remettre à zéro ?", "Attention...", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
    }
    }
     
    public void Timer()  {
    if(this.started) {
    this.s++;
    if(this.s>=60) { this.s=0; this.m++; }
    if(this.m>=60) { this.m=0; this.h++; }
    temps.setText(""+this.h+":"+this.m+":"+this.s);
     
     
     
      try{  
     Thread.sleep(1000);
     
     } 
    catch(InterruptedException ie) {
     
     } 
    Timer();
    }
    }
     
     
    }
    Donc tout d'abord ce programme créé une interface, avec un JTabbedPane, et un onglet, contenant un bouton.
    Lorsque on clique sur le bouton, on créé un nouvel objet TimePanel, qui renvoie un JPanel et on l'ajoute dans un nouvel Onglet.

    TimePanel renvoit donc un JPanel, avec dessus un JLabel ( ce qui affichera le temps ) et 3 boutons : start, stop, et raz ( qui feront l'action du chronos ).
    Une fois l'objet créé, on éxécute la méthode Timer() qui sera appelé toutes les une secondes, incrémentant aisi la variable s ( secondes ) et s'il le faut m ( minutes ) et h(heure).
    Ensuite le JLabel est mis à jour.
    Les 3 boutons recoivent des actions : start : started=true ( le chrono est en route )
    stop : starded=false; ( stop le chrono )
    raz : remize à réro.

    Voilà, bon maintenant, il y a un problème :
    Lorsque je clique sur Nouvel Onglet, le programme se bloque.
    Ca fait 2 jours que je cherche le problème, mais en vain.
    Tout ce que je sais, c'est que ca vient d ela methode Timer().
    Car sans cette méhode, l'onglet s'affiche ainsi que le TimePanel.

    Voilà, donc si vous pouvez m'aider ! Merci d'avance !

  2. #2
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    bonjour,

    ton programme se bloque parce que tu fais des sleep dans des callback Swing, bloquant ainsi le thread en charge (entre autre) de rafraîchir l'affichage, l'Event Dispatcher Thread. En fait, tous les événements (affichage, appui sur les boutons start, stop, ...) sont empilés dans la file EventQueue géré par ce thread, mais jamais dépilés car tu ne lui redonnes jamais la main. Par exemple, ta méthode Timer fait un sleep, et après se rappelle elle-même récursivement (attention risque de OutOfMemoryError), au lieu de rendre la main.
    Je te conseille de lire les tutoriaux de Sun pour comprendre comment écrire une application graphique basée sur Swing. Dans le cas de ton programme, il faut reprendre tous les callbacks, mettre en oeuvre un javax.swing.Timer, etc. bref ça ne sert à rien de tout réécrire à ta place si tu n'as pas acquis les concepts de base. Bon courage !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Points : 475
    Points
    475
    Par défaut
    Bonjour,

    Première remarque : il n'est pas très prudent d'appeler l'une de tes méthodes Timer, qui est le nom d'une classe de l'API. Mais le problème n'est pas là.

    J'ai l'impression que le Thread.sleep() du chronomètre bloque tout simplement l'affichage. En faisant du chronomètre un thread, cela résoud le problème. Voir code modifié ci-dessous qui marche chez moi.

    Ceci dit, je trouve que les appels récursifs à Timer() (maintenant run()) ne constituent pas une bonne implémentation, car c'est une récursion potentiellement infinie si l'utilisateur n'arrête pas le chronomètre (risque de débordement de la pile). Essaie d'utiliser plutôt une boucle while, ou un Timer, etc...

    Nicolas

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    import javax.swing.*;
    import java.awt.event.*;
     
    public class Chronos extends JFrame implements ActionListener {
        static int nbOnglets;
        public JTabbedPane lesChronos = new JTabbedPane();
        JPanel mainPanel = new JPanel();
        JButton ajChrono = new JButton("Nouvel Onglet");
     
        public  Chronos() {
            super("JavaChronos");
            setSize(500, 400);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            ajChrono.addActionListener(this);
            mainPanel.add(ajChrono);
            lesChronos.addTab("Main", mainPanel);
            getContentPane().add(lesChronos);
            setVisible(true);
        }
     
        public static void main(String[] arguments) {
            new Chronos();
        }
     
        public void actionPerformed(ActionEvent event) {
            AjoutChrono();
        }
     
        public void AjoutChrono() {
            TimePanel newChrono = new TimePanel();
            lesChronos.addTab("Onglet n° "+nbOnglets, newChrono);
            nbOnglets++;
        }
    }
     
    class TimePanel extends JPanel implements ActionListener, Runnable {
        JLabel temps = new JLabel("00:00:00");
        int h, m, s;
        boolean started;
        JButton start = new JButton("Start !");
        JButton stop = new JButton("Stop !");
        JButton raz = new JButton("RAZ");
     
        public TimePanel() {
            super();
            this.started=true;
            add(temps);
            add(start);
            add(stop);
            add(raz);
            start.addActionListener(this);
            stop.addActionListener(this);
            raz.addActionListener(this);
            try{
                Thread.sleep(1000);
            } catch(InterruptedException ie) {
            }
            Thread timer2Thread = new Thread(this); // AJOUT
            timer2Thread.start(); // AJOUT
            // Timer2(); // SUPPRESSION
        }
     
        public void actionPerformed(ActionEvent event) {
            Object source = event.getSource() ;
            if(source==start) {this.started=true; }
            if(source==stop) {this.started=false; }
            if(source==raz) {
                int reponse = JOptionPane.showConfirmDialog(this, "Etes-vous sûr de vouloir remettre à zéro ?", "Attention...", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            }
        }
     
        public void run()  {
            if(this.started) {
                this.s++;
                if(this.s>=60) { this.s=0; this.m++; }
                if(this.m>=60) { this.m=0; this.h++; }
                temps.setText(""+this.h+":"+this.m+":"+this.s);
                temps.revalidate(); //
                try{
                    Thread.sleep(1000);
                } catch(InterruptedException ie) { ie.printStackTrace(); } // AJOUT
                run(); // AJOUT
                //Timer2(); // SUPPRESSION
            } else {
                try{
                    Thread.sleep(100); // AJOUT
                } catch(InterruptedException ie) { ie.printStackTrace(); }
                run(); // AJOUT
            }
        }
    }

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 34
    Points : 23
    Points
    23
    Par défaut
    Merci beaucoup, ça marche !
    Par contre, je n'ai pas trop compris le code, mais c'est normal je suis débutant. Je vais maintenant mettre dans les gros bouqins Java, et tutos...
    Merci à vous deux !
    ++++

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    429
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 429
    Points : 475
    Points
    475
    Par défaut
    Pour t'aider, voici une version un peu plus propre basée sur ton code et utilisant Timer/TimerTask (seules les fonctions START et STOP sont implémentées, pas RAZ).

    Mais cela ne te dispense pas d'un peu de lecture (Swing, Timer/TimerTask, ...)

    Nicolas

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    import javax.swing.*;
    import java.awt.event.*;
    import java.util.Timer;
    import java.util.TimerTask;
     
    public class Chronos extends JFrame implements ActionListener {
        static int nbOnglets;
        public JTabbedPane lesChronos = new JTabbedPane();
        JPanel mainPanel = new JPanel();
        JButton ajChrono = new JButton("Nouvel Onglet");
     
        public  Chronos() {
            super("JavaChronos");
            setSize(500, 400);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            ajChrono.addActionListener(this);
            mainPanel.add(ajChrono);
            lesChronos.addTab("Main", mainPanel);
            getContentPane().add(lesChronos);
            setVisible(true);
        }
     
        public static void main(String[] arguments) {
            new Chronos();
        }
     
        public void actionPerformed(ActionEvent event) {
            AjoutChrono();
        }
     
        public void AjoutChrono() {
            TimePanel newChrono = new TimePanel();
            lesChronos.addTab("Onglet n° "+nbOnglets, newChrono);
            nbOnglets++;
        }
    }
     
    class TimePanel extends JPanel implements ActionListener {
        JLabel temps = new JLabel("00:00:00");
        int h, m, s;
        JButton start = new JButton("Start !");
        JButton stop = new JButton("Stop !");
        JButton raz = new JButton("RAZ");
        Timer minuteur = null;
     
        public TimePanel() {
            super();
            add(temps);
            add(start);
            add(stop);
            add(raz);
            start.addActionListener(this);
            stop.addActionListener(this);
            raz.addActionListener(this);
        }
     
        public void actionPerformed(ActionEvent event) {
            Object source = event.getSource() ;
            if(source==start) {
                if (minuteur==null) { // le chrono n'est pas en marche
                    minuteur = new Timer();
                    TimerTask tache = new TimerTask() {
                        public void run() {
                            addOneSecond();
                        }
                    };
                    minuteur.schedule(tache, 0, 1000);}
            } else {} // le chrono est déjà en route
            if(source==stop) {
                if (minuteur!=null) { // le chrono est en marche
                    minuteur.cancel();
                    minuteur = null;
                } else {} // le chrono n'est pas en marche
            }
            if(source==raz) {
                int reponse = JOptionPane.showConfirmDialog(this, "Etes-vous sûr de vouloir remettre à zéro ?", "Attention...", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            }
        }
     
        public void addOneSecond()  {
            this.s++;
            if(this.s>=60) { this.s=0; this.m++; }
            if(this.m>=60) { this.m=0; this.h++; }
            temps.setText(""+this.h+":"+this.m+":"+this.s);
        }
    }

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

Discussions similaires

  1. Problème de blocage dans mon programme
    Par Shennong dans le forum VB.NET
    Réponses: 3
    Dernier message: 05/12/2014, 11h00
  2. Réponses: 7
    Dernier message: 02/09/2005, 15h15
  3. Integrer une musique dans mon programme
    Par Tutux84 dans le forum C
    Réponses: 2
    Dernier message: 29/01/2005, 12h41
  4. [Lien]erreur dans mon programme python
    Par durnambule dans le forum Général Python
    Réponses: 11
    Dernier message: 29/01/2004, 14h59
  5. [] Utiliser AVI d'une DLL dans mon programme
    Par seb.49 dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 02/05/2003, 14h52

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