Boucle while et affichage des images

Résolu
toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention   -  
toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

j'essaie de faire un tirage aléatoire (sans remise) avec affichage d'une image différente en fonction du numéro tiré, le code fonctionne dans la console mais les images ne sont affichées qu'à la fin de la boucle while (elles se superposent toutes en même temps...)
Je ne comprends pas trop...


public class Panel extends JPanel {
	
  public void paintComponent(Graphics g){


//Image de fond 
   
    try {
				BufferedImage image = ImageIO.read(new File("photo/ztableau.png"));
				g.drawImage(image, 50, 100, null);
				} 
					catch (IOException e) {
					e.printStackTrace();
											}


int i;
String s;

String photos []={"photo/1.jpg","photo/2i.jpg","photo/3.jpg","photo/4.jpg","photo/5.jpg","photo/6.jpg"};

ArrayList<Integer> arl=new ArrayList<Integer>();
for (i=0;i<photos.length;i++){
	arl.add(i);
	}



//Génération du nombre aléatoire

while (arl.size() != 0) {

Collections.shuffle(arl);

System.out.println(arl.get(0));
    
//Faire apparaître la photo en fonction du nombre aléatoire  

	try {
				BufferedImage image = ImageIO.read(new File(photos[arl.get(0)]));
				g.drawImage(image, 480, 170, null);
				} 
					catch (IOException e) {
					e.printStackTrace();
					}
															

repaint();
arl.remove(0);
s = Isn.readString();

}
            
}}



Merci de votre aide!
:)

2 réponses

toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention  
 
Merci KX,
en effet, je débute et avance en tatonnant dans la programmation graphique..
Merci pour ton exemple, je crois comprendre ce que tu veux dire!
Ce que je n'arrive pas en partant de cet exemple c'est rajouter une image de fond...
quelle méthode employer et où faut-il la placer??

Merci
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Je reprends en partie mon code d'exemple pour rajouter une image, juste pour te montrer ce qui change :

int n=0;

// Chargement de l'image une seule fois dans le programme.
Image img = new ImageIcon("test.png").getImage();
// Remarque : j'utilise ImageIcon parce que si tu veux créer un fichier JAR avec tes images dedans ImageIO ne les retrouveras pas mais ImageIcon si.

@Override
public void paint(Graphics g)
{
    super.paint(g);
	
    System.out.println("paint "+(++n));
    
    // Affichage de l'image à chaque rafraîchissement de la fenêtre.
    g.drawImage(img, 0, 0, this);
    // Remarque : ici l'opération est rapide car l'image est déjà en mémoire.

    ...

Remarque : il est important que l'affichage de l'image soit après le super.paint et avant l'affichage des chiffres car tout est superposé.
0
toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention  
 
J'ai une erreur:
symbol: class Image

Il faut surement rajouter quelque chose dans l'en-tête mais je ne trouve pas quoi...
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
import java.awt.Image;
import javax.swing.ImageIcon;
0
toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention  
 
Ok! C'est vachement plus clair ccomme ça! :)

Maintenant, est-ce que je peux charger toutes les images avec:

Image img = new ImageIcon("test.png").getImage();


puis les classer dans un tableau du genre:

photos [] = {img , img1,...}


pour pouvoir les appeler ensuite avec quelque chose du genre:

g.drawImage(photos[1], 0, 0, this);


??
0
toto5812 Messages postés 57 Date d'inscription   Statut Membre Dernière intervention  
 
ça fonctionne avec ça:


Image img2 = new ImageIcon(photos[arl.get(0)]).getImage(); 
g.drawImage(img2, 15, 100, this);
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
Le problème le plus évident c'est que tu as mis tout ton code à l'intérieur de paintComponent ce qui est extrêmement faux !

La méthode paintComponent (de même que paint en awt) est faite uniquement pour dire ce qui doit être affiché au moment où on lui demande. Cela signifie :
1) rien ne sera affiché avant que la méthode paintComponent ne soit terminé
2) la méthode paintComponent sera appelé à chaque fois qu'il faut réafficher la fenêtre, par exemple, à chaque fois que tu redimensionnes ta fenêtre.

Il faut donc que la méthode soit la plus rapide à exécuter possible (pour que l'affichage soit fluide), en particulier il ne faut pas que tu fasses de ImageIO.read dans cette méthode, car cela signifie que tu vas relire tout tes fichiers à chaque fois que la fenêtre se rafraîchit ce qui prend beaucoup de temps.

De plus, il ne faut pas faire non plus ton Collections.shuffle à ce niveau là, car sinon, à chaque nouvel affichage, toutes tes photos apparaîtront dans un nouvel ordre, ce qui va être très moche !

Enfin, n'oublie pas d'appeler la méthode super.paintComponent(g); au tout début de ta méthode, il faut le faire à chaque fois que tu redéfinis une méthode de ton composant (ton JPanel ici)

Voici un exemple simple pour voir ces deux problèmes.
À tester : change la taille de la fenêtre. Tu verras s'afficher le message "paint" à chaque fois que la méthode a été appelé, et que les chiffres sont sans arrêt modifié puisque le shuffle agit à chaque fois.

import java.awt.Color;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.swing.JFrame;

public class Panel
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame()
        {
            private static final long serialVersionUID = 1;
            
            int n=0;
            
            @Override
            public void paint(Graphics g)
            {
                super.paint(g);
                
                System.out.println("paint "+(++n));
                
                List<String> list = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
                Collections.shuffle(list);
                
                g.setColor(Color.BLACK);
                for (int i=0; i<list.size(); i++)
                    g.drawString(list.get(i), 10+10*i, 45);
            }
        };
        
        frame.setSize(90,60);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
-1