Paint_component jamais appelé par repaint()

dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009 - 2 oct. 2009 à 00:08
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009 - 6 oct. 2009 à 20:54
[b]Bonjour,
je tente en vain de rafraichir une image en utilisant repaint(), mais rien ne se passe (paint_component n'est jamais appelé).
J'utilise un thread qui télécharge une image et qui est censé la mettre à jour


ci-joint le thread "Acquisition_video" permettant le téléchargement et l'affichage de l'image, ainsi qu'un extrait du code de génération de la fenêtre et du lancement du thread.

Merci de votre aide/b

public class Acquisition_video extends JLabel implements Runnable
{
private DataInputStream Entree_video_in;
private ImageIcon image;
byte[] buffer_image = new byte[100000];
public Acquisition_video(DataInputStream entree)
{
//Connexion Video port 9101
Entree_video_in=entree;

}


public void run()
{
byte[] entete = new byte[4];
byte[] longueur = new byte[2];
int lg1;
int lg2;
int lg;



try
{
while(true)
{
System.out.println ("Acquisition video");
//Lecture entete de type B0B0D000
//byte[] entete = new byte[4];
Entree_video_in.readFully(entete);

//Lecture du nombre d'octets de l'image
//byte[] longueur = new byte[2];
Entree_video_in.readFully(longueur);


lg1=((longueur[1]&0xff)<<8);
lg2=longueur[0]& 0xff;
lg = lg1+lg2;

//Lecture image
Entree_video_in.readFully(buffer_image,0,lg);

//Affichage image
//image = new ImageIcon (buffer_image);

repaint();

try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
catch(IOException e)
{ System.out.println(e);
System.out.println ("probleme thread");
System.exit(0);
}
}



public void paintComponent(Graphics g)
{
super.paint(g);
image = new ImageIcon(buffer_image);
g.drawImage(image.getImage(),10,120,null);
}


}



class Fenetre extends JFrame implements ActionListener
{
Acquisition_video canvas;
private static final long serialVersionUID = 1L;


private InputStream flux_video_in;
private DataInputStream Entree_video_in;
private Socket soc_video_in;
private OutputStream flux_video_out;
private OutputStreamWriter sortie_video_out;
private Socket soc_video_out;
private JLabel label;

public byte[] buffer_image = new byte[100000];

private Container contenu;
private int test;


public Fenetre()
{

super();
canvas = new Acquisition_video(Entree_video_in);
setSize(350,400);
label = new JLabel();
contenu=getContentPane();
contenu.setLayout(new FlowLayout());
contenu.add(canvas);
.......

public void init() throws IOException
{
//Connexion Video
soc_video_in = new Socket (Ad_ip,port_video);
flux_video_in = soc_video_in.getInputStream();
flux_video_out = soc_video_in.getOutputStream();
Entree_video_in = new DataInputStream(flux_video_in);

Acquisition_video vid= new Acquisition_video(Entree_video_in);
vid= new Acquisition_video(Entree_video_in);

Thread Video=new Thread (vid);
Video.start();

15 réponses

uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
2 oct. 2009 à 04:25
Nous devond remplacer ceci:
super.paint(g);

par ceci:
super.paintComponent(g);
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
2 oct. 2009 à 08:53
J'ai essayé sans succès.
Le problème, c'est que je n'entre jamais dans paintcomponent (malgré l'execution de repaint())
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
3 oct. 2009 à 04:53
Si tu n'entre pas dans paintComponent(), c'est que le composant n'est pas visible. Tu peux faire le test en ajoutant qulequechose comme ceci:
System.out.println(isVisible());
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
3 oct. 2009 à 05:16
...ou ceci:

System.out.println(isShowing() + " " + getClass().getName());
Component parent = getParent();
while (parent != null) {
[*] System.out.println(parent.isShowing() + " " + parent.getClass().getName());
[*] parent = parent.getParent();
}

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
3 oct. 2009 à 10:54
En executant System.out.println(isVisible()), j'ai le retour 'true'

Par contre, en en executant
System.out.println(isShowing() + " " + getClass().getName());
Component parent = getParent();
while (parent != null)
{
System.out.println(parent.isShowing() + " " + parent.getClass().getName());
parent = parent.getParent();
}
j'ai le retour false (parent est toujours égal à null).
je précise que j'ai fait ces tests en plaçant ces lignes de commandes dans la méthode run() de la classe "Acquisition_video"
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
3 oct. 2009 à 12:36
Cela confirme ce que je disais: tu n'entre pas dans paintComponent(), parceque le composant est invisible (il n'appartient même pas à une fenêtre visible, car il n'a aucun parent).
Conclusion: tu as créé deux instances du même composant: un des deux est visible à l'écran et l'autre est invisible. Tu fais les repaint() sur celui qui est invisible: c'est pas étonnant qu'il ne se passe rien à l'écran!
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
3 oct. 2009 à 13:46
D'accord mais je ne vois pas où je crée 2 instances du même composant.

J'ai une classe principale ("Fenetre" dans mon programme) dans laquelle j'ai créer mon panel et les différents éléments graphiques, et j'ai le Thread "Acquisition video" dans lequel j'essaie de rafraichir une image).
J'en déduit qu'un argument passe mal lors du lancement du Thread chargé de rafraichir l'image, mais je ne vois pas ...

Quand tu parles de 2 instances du même composant, tu parles de l'image ou du panel complet?
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
3 oct. 2009 à 16:54
Je parle du composant qui dessine l'image dans paintComponent(..). Ton application fais au moins deux fois "new Acquisition_video(..)".
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
3 oct. 2009 à 17:38
En effet, en ayant une seule instance, le code :
System.out.println(isShowing() + " " + getClass().getName());
Component parent = getParent();
while (parent != null)
{
System.out.println(parent.isShowing() + " " + parent.getClass().getName());
parent = parent.getParent();
}

me renvoi :
true Acquisition_video
true javax.swing.JPanel
true javax.swing.JLayeredPane
true javax.swing.JRootPane
true Fenetre

mais je ne rentre toujours pas dans paintcomponent ...
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
3 oct. 2009 à 18:51
Il y a trois possiblités:
1. le composant se trouve dans un ScrollPane visible mais le composant n'est actuellement pas dans le view port du ScrollPane,
2. le composant est caché par un autre composant ou Container.
3. il y a un problème dans painComponent: tu peux facilement vérifier si paintComponent n'est vraiment pas exécutée en ajoutant ceci à l'intérieur de la méthode paintComponent:
System.out.println("paintComponent a été exécutée");
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
3 oct. 2009 à 20:20
Pour le point 3, je suis sûr que paintComponent n'est pas appelé.
Pour les points 1 ou 2, comment savoir ?

Ce que je ne comprend pas, c'est qu'en utilisant en seul Thread (en gérant l'affichage dans la Class Fenetre), j'arrive à rafraichir mon image.
Je suis embêté depuis que j'ai crée un autre thread (Acquistion video).

Autre point que je ne comprend pas, c'est que lorsque je lorsque je fait un extends JPanel au lieu de extends JLabel, le repaint() appelle paint_component, mais l'image n'est pas rafraichie.

En tout cas, merci beaucoup pour ton aide.
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
4 oct. 2009 à 00:21
Contrôle un fois la grandeur (getSize()): si elle est zéro, la méthode paintComponent n'est pas appelée!
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
4 oct. 2009 à 00:43
En effet, la méthode paintComponent n'est pas appelée :
getsize() me renvoi java.awt.Dimension[width=0,height=0]
uhrand Messages postés 491 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 15 juillet 2012 9
4 oct. 2009 à 07:53
Dan ce cas, il suffit de mettre une grandeur et le problème est résolu!
dulbala Messages postés 9 Date d'inscription mardi 25 août 2009 Statut Membre Dernière intervention 6 octobre 2009
6 oct. 2009 à 20:54
Le problème est partiellement réglé en définissant la taille dans paint_component et en faisant un extends JPanel.
Néanmoins, il me colle l'image juste après les boutons et elle est à moitié bouffée . Je pense que le pb vient du fait qu'au moment de réserver l'emplacement pôur l'image, il voit qu'elle a une taille nulle.

N'ayant pas réussi à la placer où le voulais, j'ai finalement résolu mon problème avec VEP (sous eclipse) qui gère l'interface graphique bien mieux que moi.

Uhrand, merci encore pour ton aide.
Rejoignez-nous