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 :

Difficulté maj du repaint


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 18
    Par défaut Difficulté maj du repaint
    Bonjour,

    J'ai voulu gérer chaque pixel dans une fenêtre. J'ai donc crée un tableau de pixels qui est égale à la résolution de ma fenêtre. Et dans chaque pixel, il y a 2 entiers pour la position et 4 entiers pour la gestion de la couleur.

    Lorsque j'éxécute, seulement quelques pixels au hasard s'allument dans la fenêtre.

    Ce qui est bizarre, c'est que quand je fais un threads sleep apres le repaint, à ce moment là tous les pixels sont coloriés.

    Y a t il un moyens de gérer tous les pixels de façon fluide et pourquoi cette erreur.

    La classe Fenêtre:
    Code java : 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
     
    import javax.swing.JFrame;
     
    public class Fenetre extends JFrame{
     
     
    	int n;
    	int m;
    	Panneau pan;
    	Pixel []tab;
     
     
     
            public Fenetre(int n, int m){
            	this.n =n;
            	this.m =m;
            	int k =0;
            	this.tab = new Pixel[n*m];
            	for(int i =0; i<n;i++){
            		for(int j =0; j<m; j++){
            		tab[k] = new Pixel(i,j , 255, 0, 0, 100);
            		k++;
            		}
            	}
                pan = new Panneau(n,m, tab[0]);
                this.setSize(n, m);
                this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                this.setLocationRelativeTo(null);
                this.setContentPane(pan);
                this.setVisible(true);
     
     
                   go();
            }
     
            private void go(){
            	Pixel tmp;
            	for(int i =1; i<n*m;i++){
            		tmp = tab[i];
            		pan.setP(tmp);
            		pan.repaint();
            		try{
           			 Thread.sleep(1);//Si on enlève cette partie, on a un nuage de point
           		 } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
            		System.out.println(i);
     
            	}
     
     
            }
     
    }

    La classe Panneau:
    Code java : 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
     
     
     
    import java.awt.*;
    import javax.swing.*;
     
    public class Panneau extends JPanel {
     
    	int n,m;
    	Pixel p;
     
    	Panneau(int n, int m, Pixel p){
    		this.n =n;
    		this.m =m;
    		this.p = p;
     
    	}
     
    	public void paintComponent(Graphics g){
    			Color c = new Color(p.getR(),p.getG(),p.getB(),p.getA());
    			g.setColor(c);
    			g.drawRect(p.getX(),p.getY(), 1, 1 );
    			System.out.println(">>>>>"+p.getX()+" " +p.getY());
     
     
     
     
         }
     
    	void setP(Pixel p){
    		this.p =p;
    	}
     
    }

    La classe Pixel:

    Code java : 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
     
     
     
    public class Pixel {
     
    	int x,y,r,g,b,a;
     
    	Pixel(int x, int y, int r,int g, int b, int a){
    		this.x =x;
    		this.y =y;
    		this.r =r;
    		this.g =g;
    		this.b =b;
    		this.a =a;
     
    	}
     
    	public int getX() {
    		return x;
    	}
     
    	public void setX(int x) {
    		this.x = x;
    	}
     
    	public int getY() {
    		return y;
    	}
     
    	public void setY(int y) {
    		this.y = y;
    	}
     
    	public int getR() {
    		return r;
    	}
     
    	public void setR(int r) {
    		this.r = r;
    	}
     
    	public int getG() {
    		return g;
    	}
     
    	public void setG(int g) {
    		this.g = g;
    	}
     
    	public int getB() {
    		return b;
    	}
     
    	public void setB(int b) {
    		this.b = b;
    	}
     
    	public int getA() {
    		return a;
    	}
     
    	public void setA(int a) {
    		this.a = a;
    	}
     
     
    }





    Merci.

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Au lieu de faire un JPanel par pixel je te conseille très fortement de créer un seul JPanel responsable d'afficher l'intégralité des pixels pour des histoires de performance et de cohérence au niveau de l'EDT. De plus le nombre de repaint à réaliser en sera amplement moindre. De fait au lieu d'avoir la matrice de Pixel au niveau de ta JTable, elle devra être contenue dans ta classe panneau, qui bouclera dessus pour dessiner chaque pixel dans la méthode paintComponent.

    Secondement, il est interdit de faire du Thread.sleep dans le thread qui s'occupe de Swing, sous peine de freezer l'interface graphique?

    De fait l'intégralité de ta méthode go devra être réalisé dans un thread séparé.

    Lecture obligatoire pour les personne débutant en Swing: http://gfx.developpez.com/tutoriel/j...ing-threading/

  3. #3
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 899
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par sinok Voir le message
    un JPanel par pixel
    ... pardon je m'étrangle de stupeur...

    Autant pour x et y je comprends mais pourquoi stocker r, g, b et a chacun dans un entier sachant que chacune de ces valeurs ne dépasse pas 255. Ce n'est pas pour rien qu'il est commun de stocker une couleur sRGB sous forme d'un unique entier consitué de 4 octets argb...
    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
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Citation Envoyé par bouye Voir le message
    ... pardon je m'étrangle de stupeur...
    Ca m'a fait la même...

  5. #5
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 050
    Par défaut
    Salut,

    Tu n'a pas la bonne approche pour dessiner. Sinok t'as donné toutes les pistes. La méthode paintComponent doit dessiner intégralement ce qu'il y a à dessiner, alors que toi tu dessine à tour de rôle les pixels. La méthode paintComponent ne doit pas dessiner 1 pixel mais tous les pixels : ton panel est susceptible de se redessiner lorsque l'utilisateur fera certaines choses (redimensionnement de fenêtre par exemple).

    Je pense que tu doit être débutant, je te conseil de lire des tutoriels sur le dessin en Java2D.

    Voici une solution pour que tes pixels se dessinent correctement avec évidemment un temps de latence important car ta méthodologie n'est pas très performante (il existe des méthodes et objets pour gérer les pixels, ce serait déjà mieux). Je me suis contenter de transmettre ton tableau au Panel qui se charge de dessiner l'ensemble des pixels :

    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
    import java.awt.Dimension;
    import javax.swing.JFrame;
     
    public class Fenetre extends JFrame {
     
    	public Fenetre(int n, int m) {
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		int k = 0;
    		Pixel[] tab = new Pixel[n * m];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < m; j++) {
    				tab[k] = new Pixel(i, j, 255, 0, 0, 100);
    				k++;
    			}
    		}
    		Panneau pan = new Panneau(tab);
    		pan.setPreferredSize(new Dimension(n, m));
    		this.setContentPane(pan);
    		pack();
    		this.setLocationRelativeTo(null);
    		this.setVisible(true);
    	}
     
    	public static void main(String[] args) {
    		new Fenetre(200, 200);
    	}
     
    }
    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
    import java.awt.*;
    import javax.swing.*;
     
    public class Panneau extends JPanel {
     
    	Pixel[] tab;
     
    	Panneau(Pixel[] tab) {
    		this.tab = tab;
    	}
     
    	public void paintComponent(Graphics g) {
    		for (int i = 0; i < tab.length; i++) {
    			Pixel pixel = tab[i];
    			g.setColor(new Color(pixel.getR(), pixel.getG(), pixel.getB(),
    					pixel.getA()));
    			g.drawRect(pixel.getX(), pixel.getY(), 1, 1);
    		}
    	}
     
    }
    @sinok : à moins que j'ai mal compris ce que tu voulais dire, il n'utilise pas un JPanel par pixel, mais un objet Pixel par pixel, le tout dans un seul JPanel.

  6. #6
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Sa classe Panneau est un JPanel dont la méthode paintComponent dessine un seul pixel.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 18
    Par défaut
    Pour une fenetre 200x200, il faut à plus de 5 secondes pour que l'image apparaissent.

    Je voulais suivre un algo que j'ai trouvé ici : http://www.gnurou.org/writing/linuxmag/sdl/partie4 pour faire un effet de feu.

    Est ce que java n'est pas fait pour ça, ou le code n'est pas assez optimisé?
    Je suis en train de lire les tutos et celui des threads aussi, en espérant arriver à un résultat correct.

  8. #8
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Dans le cas présent c'est un problème avec ton code.
    As tu essayé la proposition de Visiwi?

  9. #9
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 050
    Par défaut
    Citation Envoyé par Zozzio Voir le message
    Est ce que java n'est pas fait pour ça, ou le code n'est pas assez optimisé ?
    Je doute que tu parvienne à un résultat convainquant en Java2D. SDL est de plus bas niveau, c'est donc bien plus performant. Pour faire ce genre de chose en Java, il faudra probablement te tourner vers des librairies telle que LWJGL ou JOGL. Il existe aussi un binding Java de SDL (De mémoire je crois avoir vu un tutoriel java qui m'a semblé assez bien sur le site) . SDL sera sans doute plus facile à manipuler.

  10. #10
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Citation Envoyé par visiwi Voir le message
    Je doute que tu parvienne à un résultat convainquant en Java2D.

    Ou pas

    http://dwcope.freeshell.org/work/2d/javafire.php

    Et encore c'est codé à la bourrine sans thread séparé ou quoi que ce soit de vraiment propre.

  11. #11
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 050
    Par défaut
    Oui, effectivement Java2D est plus performant que je n'aurais pensé. Ça tourne très bien même !

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 18
    Par défaut
    Citation Envoyé par sinok Voir le message
    Dans le cas présent c'est un problème avec ton code.
    As tu essayé la proposition de Visiwi?
    Oui, c'est avec la proposition de Visiwi ce temps de chargement là. En tous cas ce qui est sûr c'est que c'est possible, merci pour le lien je vais étudier le code.

    Merci à vous tous.

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

Discussions similaires

  1. Obligatoire : lisez les règles du forum : MAJ 06/08/2010
    Par Anomaly dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 0
    Dernier message: 03/07/2008, 13h46
  2. maj 1ère lettre d'une chaine
    Par access001 dans le forum Requêtes
    Réponses: 5
    Dernier message: 04/07/2003, 12h27
  3. MAJ d'une table sous SQL Server par insertion
    Par keish dans le forum Langage SQL
    Réponses: 6
    Dernier message: 11/06/2003, 16h23
  4. [web]maj de pages
    Par Gogoye dans le forum Web
    Réponses: 3
    Dernier message: 17/06/2002, 18h25

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