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

AWT/Swing Java Discussion :

[SWING][THREAD][JProgressBar][Graphics2D] c'est pas gagné !


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut [SWING][THREAD][JProgressBar][Graphics2D] c'est pas gagné !
    Bonjour a tous,

    Voila 5 heures que je cherche desesperemment a resoudre un probleme de JProgressBar et rien n'y fait !
    Pour faire simple :
    J'ai une fenetre splittée en 2, a gauche un boutton et une JProgressBar, a gauche un objet Graphics2D.
    Lorsque je clic que le boutton, je voudrais qu'il augmente le JProgressBar au fur et a mesure que les calculs pour le Graphics2D se font ...
    Donc j'ai un

    /*ActionListener*/
    public void actionPerformed (ActionEvent evt){
    Object source = evt.getSource();
    if (source == b1){
    pd.addGraphListener(this);

    /*Thread JProgressBar*/
    Thread runner = new Thread(new Runnable(){
    public void run(){
    refreshProgress(maBarre);
    }
    });
    runner.start();

    /*Graphics*/
    pd.repaint();
    pd.validate();
    }

    avec

    public void refreshProgress(JProgressBar jpb){

    for( int i = 0; i < 100; i++ ) {
    jpb.setValue(i);
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {e.printStackTrace();}
    }
    }


    Le probleme est le suivant, la JProgressBar se met UNIQUEMENT une fois que tout l'actionPerformed est terminé, et donc une fois que mon graph est fait ! !!! Pourtant l'utilisation du Thread me permet bien de faire les deux taches en parallele. Ce qui pose pb, c'est la rafraichissement de la fenetre ... j'ai l'impression que je n'ai pas la main que les objets swing de ma fenetre tant que l'actionPerformed tourne !

    J'ai egalement tenté les methodes invokeLater mais celle ci permette de passer en priorité l'objet runnable sur l'EDT ... or moi, je voudrais qu'il soit fait en simultané

    merci 1000 fois a ceux qui prendront le temps de m'aider !
    Nico

  2. #2
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    Ce truc va me rendre completement fou !
    J'ai essayé de lancer le paint() de mon objet dans un thread mais ca ne marche tjrs pas, j'ai l'impression que les actions sont quand meme empilées dans l'EDT, alors qu'elle devrait etre spécifique au thread lancé !
    Je pense que sur ce coup, je vais avoir besoin de qq'un d'expérimenté ...

    PS: j'ai fait une petite erreur dans mon message precedent, le boutton à gauche et le Graphics2D a droite, evidemment ;-)

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    Penser au

    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
    package test;
     
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
     
    public class TestProgressBar extends JFrame implements ActionListener {
      private JProgressBar jpb;
      private JButton b1;
     
      public TestProgressBar() {
        super();
        jpb = new JProgressBar(0, 100);
        b1 = new JButton("Start");
        b1.addActionListener(this);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(b1);
        setLayout(new BorderLayout());
        add(buttonPanel, BorderLayout.WEST);
        add(jpb, BorderLayout.SOUTH);
      }
     
      public static void main(String ...args) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            TestProgressBar dialog = new TestProgressBar();
            dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            dialog.setVisible(true);
            dialog.pack();
          }
        });
      }
     
      public void refreshProgress(JProgressBar jpb) {
        try {
          for (int i = 0; i < 100; i++) {
            jpb.setValue(i);
            jpb.repaint();
            Thread.sleep(100);
          }
        }
        catch (InterruptedException e) {
          e.printStackTrace();
        }
        finally {
          b1.setEnabled(true);
        }
      }
     
      /** {@inheritDoc}
       */
      public void actionPerformed(ActionEvent evt) {
        Object source = evt.getSource();
        if (source == b1) {
          b1.setEnabled(false);
          jpb.setValue(0);
          /*Thread JProgressBar*/
          Thread runner = new Thread(new Runnable() {
            /** {@inheritDoc}
             */
            public void run() {
              refreshProgress(jpb);
            }
          });
          runner.setPriority(Thread.NORM_PRIORITY);
          runner.start();
        }
      }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    merci, mais ca ne resoud pas mon soucis !
    mais j'ai un peu avancé ... lorsque je lance mon thread pour ma JProgressBar, je suis obligé de faire appel a invokeLater pour que le refraichissement se fasse dans l'EDT. Le soucis c'est que la pile d'EDT contient deja tout ce qu'il y a dans mon paint() ! a savoir 55000 action fill et draw !

    Donc j'ai pensé a lancer le paint dans un autre thread, afin que celui-ci ne soit plus executer dans l'EDT ! Mais ca ne marche pas, si je fais :

    <code>
    public void actionPerformed (ActionEvent evt){
    Object source = evt.getSource();
    if (source == b1){
    Thread runner2=new Thread (new Runnable(){
    public void run(){
    pd.repaint();
    pd.validate();

    }
    });
    runner2.start();

    }

    </code>

  5. #5
    Membre éprouvé Avatar de White Rabbit
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 122

  6. #6
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    Bien, apres mure reflexion, je pense que c'est tout simplement impossible !!
    La raison est la suivante :
    Toute les opérations graphiques doivent passer par l'EDT !
    Donc utiliser une JProgressBar pour montrer l'avancement d'un long algo, pas de pb a condition que cet algorithme de touche pas à l'EDT !
    Dans mon cas, mon long traitement consiste a dessiner 55000 points sur un graph, et passe donc par l'EDT.
    Je me retrouve donc avec mon EDT dans lequel sont empilés à la fois le traitement de la JProgressBar, et mes 55000 draw ! Reste a voir si je peux jouer avec l'ordre d'empilement ...

    Peut-etre que je m'egart

  7. #7
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Tu peux générer autant de points que tu veux dans la mesure ou tu ne bloques pas l'EDT. J'ai repris to exemple ci après :
    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
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    package test;
     
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.util.Random;
     
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;
     
    public class TestProgressBar extends JFrame implements ActionListener {
        private JProgressBar jpb;
     
        private JLabel imgLabel;
     
        private BufferedImage image;
     
        private JButton b1;
     
        private final static int MAX_POINTS = 1000;
     
        private static final int IMG_WIDTH = 600;
     
        private static final int IMG_HEIGHT = 400;
     
        public TestProgressBar() {
            super();
     
            image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_3BYTE_BGR);
     
            jpb = new JProgressBar(0, MAX_POINTS);
            b1 = new JButton("Start");
            b1.addActionListener(this);
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(b1);
     
            imgLabel = new JLabel(new ImageIcon(image));
            getContentPane().setLayout(new BorderLayout());
            getContentPane().add(buttonPanel, BorderLayout.WEST);
            getContentPane().add(imgLabel, BorderLayout.CENTER);
            getContentPane().add(jpb, BorderLayout.SOUTH);
        }
     
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    TestProgressBar dialog = new TestProgressBar();
                    dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    dialog.setVisible(true);
                    dialog.pack();
                }
            });
        }
     
        private Random r = new Random();
     
        private void generatePoints() {
            for (int i = 0; i < MAX_POINTS; i++) {
                Point p = randomPoint();
                Color c = randomColor();
     
                printPoint(p, c);
                updateBar(i+1);
     
                System.out.println("n°:" + i);
                if (!SwingUtilities.isEventDispatchThread()) {
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    System.err.println("generate Point from EDT");
                }
            }
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    b1.setEnabled(true);
                }
            });
        }
     
        private void updateBar(final int i) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    jpb.setValue(i);
                    jpb.repaint();
                    System.out.println("bar updated: " + i);
                }
            });
        }
     
        private void printPoint(final Point p, final Color c) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    image.setRGB(p.x, p.y, c.getRGB());
                    imgLabel.repaint();
                    System.out.println("point add: " + p);
                }
            });
        }
     
        private Point randomPoint() {
            return new Point(r.nextInt(IMG_WIDTH), r.nextInt(IMG_HEIGHT));
        }
     
        private Color randomColor() {
            return new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
        }
     
        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == b1) {
                b1.setEnabled(false);
                jpb.setValue(0);
     
                Thread t = new Thread(new Runnable() {
                    public void run() {
                        generatePoints();
                    }
                });
                t.start();
            }
        }
    }

  8. #8
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    Et le fait de gérer la jProgressBar et le dessin dans le meme thread ne pose pas de soucis ?!

  9. #9
    Membre expérimenté
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Par défaut
    Attention le dessin et toutes les actions de modification de l'UI (dessin, refresh d'images, modif de progress) sont fait dans l'EDT contrairement à la génération des points et le calcul de l'indice de barre de progression (il faut voir ces 2 actions comme un service métier, cela pourrait être remplacé par le calcul complêxe d'une image) qui sont effectués dans une thread à part.

    Exécute le code pour t'en convaincre.

    -----------------
    Matthieu BROUILLARD
    Mon blog

  10. #10
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    Egalement tu n'es pas non-plus oblige de tout peindre dans l'EDT directement sur l'ecran, tu peux tres bien peindre dans une autre thread dans un image offscreen qui sera elle-meme composee sur l'ecran pendant l'EDT.

    Ou comme le dit McFoggy si tu decomposes suffisement bien ton travail, tu generes/calcules tes points dans une thread a part (qui change l'etat de la progress bar) et parallement dans l'EDT tu dessines les points disponibles qui ont ete calcules par l'autre thread.

    Tu as plusieurs solutions pour resoudre ton probleme.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  11. #11
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    Merci du coup de main ! Mais il y a encore un truc qui doit m'echapper. J'ai repris ton code et je l'ai modifié pour le faire travailler dans un Graphics2D, et là !surprise, les points ne s'affichent plus !!!

    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
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.util.Random;
    import java.awt.geom.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;
     
    public class TestProgressBar extends JFrame implements ActionListener {
        private JProgressBar jj;
     
        private DrawClass dc;
        private JButton b1;
        private final static int MAX_POINTS = 100;
     
        public TestProgressBar() {
            super();
            jj = new JProgressBar(0, MAX_POINTS);
            b1 = new JButton("Start");
            b1.addActionListener(this);
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(b1);
     
            dc=new DrawClass(jj);
    	getContentPane().setLayout(new BorderLayout());
            getContentPane().add(buttonPanel, BorderLayout.WEST);
            getContentPane().add(dc, BorderLayout.CENTER);
    	getContentPane().add(jj, BorderLayout.SOUTH);
        }
     
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    TestProgressBar dialog = new TestProgressBar();
                    dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		dialog.setSize(500,500);
                    dialog.setVisible(true);
                }
            });
        }
     
        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == b1) {
                b1.setEnabled(false);
    	    dc.setAction();
                jj.setValue(0);
     
                Thread t = new Thread(new Runnable() {
                    public void run() {
                        dc.generatePoints();
                    }
                });
                t.start();
            }
        }
     
     
     
        class DrawClass extends JPanel{
    	private JProgressBar jpb;
    	private boolean action=false;
    	Graphics2D g2;
     
     
    	public DrawClass(JProgressBar j){
    	    jpb=j;
    	}
     
    	private void printPoint(final Point p, final Color c) {
    	    SwingUtilities.invokeLater(new Runnable() {
    		    public void run() {
    			g2.setColor(c);
    			Rectangle2D.Float rd = new Rectangle2D.Float(p.x,p.y,5,5);
    			g2.fill(rd);
    			System.out.println("point add: " + p);
    		    }
    		});
    	}
     
    	public void setAction(){
    	    action=true;
    	}
     
    	public void paint(Graphics g){
    	    g2 =(Graphics2D)g;
    	    if (action){
    		g2.clearRect(0,0,getSize().width,getSize().height);
    		generatePoints();
    	    }
    	    else
    		g2.clearRect(0,0,getSize().width,getSize().height);
    	}
     
    	private Random r = new Random();
     
    	private void generatePoints() {
    	    for (int i = 0; i < MAX_POINTS; i++) {
    		Point p = randomPoint();
    		Color c = randomColor();
    		printPoint(p,c);
    		updateBar(i+1);
     
    		System.out.println("n:" + i);
    		if (!SwingUtilities.isEventDispatchThread()) {
    		    try {
    			Thread.sleep(20);
    		    } catch (Exception e) {
    			e.printStackTrace();
    		    }
    		} else {
    		    System.err.println("generate Point from EDT");
    		}
            }
    	    SwingUtilities.invokeLater(new Runnable() {
    		    public void run() {
                    b1.setEnabled(true);
    		    }
    		});
    	}
     
    	private void updateBar(final int i) {
    	    SwingUtilities.invokeLater(new Runnable() {
    		    public void run() {
    			jpb.setValue(i);
    			jpb.repaint();
    			System.out.println("bar updated: " + i);
    		    }
    		});
    	}
    	private Point randomPoint() {
    	    return new Point(r.nextInt(getSize().width), r.nextInt(getSize().height));
    	}
     
    	private Color randomColor() {
    	    return new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
    	}
        }
     
     
     
    }

  12. #12
    Membre averti
    Inscrit en
    Août 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 15
    Par défaut
    Il y a une erreur dans l'actionPerformed(), évidement il faut appeler dc.repaint(); et non dc.generatePoints(). Mais ca ne resout pas le pb ! toujours pas de points à l'écran.

Discussions similaires

  1. Réponses: 8
    Dernier message: 04/08/2010, 12h29
  2. c'est pas gagné ;)
    Par arnofly dans le forum Vidéo
    Réponses: 3
    Dernier message: 28/01/2010, 13h21
  3. Réponses: 6
    Dernier message: 01/12/2009, 11h52
  4. Coordooné c'est pas gagné..
    Par corgato dans le forum Qt
    Réponses: 8
    Dernier message: 25/01/2008, 22h59
  5. [SWING] Ma table JTABLE n'est pas éditable
    Par Dahu dans le forum Composants
    Réponses: 7
    Dernier message: 06/04/2006, 12h22

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