Préchargement d'image [Résolu]

Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 26 août 2008 à 23:14 - Dernière réponse : Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention
- 27 août 2008 à 18:38
Bonjour, j'ai aujourd'hui une vraie question de vrai débutant à poser :

Y  a-t-il un moyen de précharcher une image, et de ne rendre la main au programme qu'une fois que c'est fait ? Car j'utilise des panneaux dont la méthode paintComponant affiche une petite image, dont l'objet correspondant a été créé dans le constructeur.
Or ces images ont tendance (environ une fois sur deux) à ne pas toutes apparaître à l'apparition de la fenêtre, mais à le faire si je la rabats et l'aggrandis (repaint, avec l'intervalle pour finir de charger). J'ai cru comprendre que le constructeur de ImageIcon chargeait complètement avant d erendre la main et que le getImage d eToolkit chargeait en arrière plan, avant de comprende l'inverse. En tout cas, j'ai tuilisé ces 2 méthodes sans remarquer de différence, et j'ai même essayer de faire une boucle avec ImageIcon :

    icone = new ImageIcon(getClass().getClassLoader().getResource(add));
    for(int i = 1; icone.getImageLoadStatus() != MediaTracker.COMPLETE; i++)
      {
   System.out.println(Integer.toString(icone.getImageLoadStatus()));
   i--;
   }

Ma fenêtre n'apparaissait pas, et en ajoutant le println  j'ai compris que le LoadStatus restait bloqué à 2 et n'avançait pas tant que durait la boucle, qui je suppose ne devait pas laisser de temps pour charger l'image en arrière plan.
Un LoadStatus d e2 correspond à l'état ABORTED, or les images apparaissent bien avec un repaint() tardif (Pas la peine d'appeler repaint^après l'apparition de la fenêtre, c'est sans effet)

Nitruk
Afficher la suite 

Votre réponse

10 réponses

Meilleure réponse
Twinuts 5270 Messages postés dimanche 4 mai 2003Date d'inscription 9 juillet 2018 Dernière intervention - 27 août 2008 à 16:32
3
Merci
Salut,

tu peux toujours essayer avec la méthode 'getResourceAsStream'
si non utiliser la classe ResourceLocator dispo ICI (2ème message)

bien que normalement tu ne devrais pas avoir de problèmes (je n'ai pas le même problème en local avec une image dans le jar)...

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO

Merci Twinuts 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 78 internautes ce mois-ci

Commenter la réponse de Twinuts
Twinuts 5270 Messages postés dimanche 4 mai 2003Date d'inscription 9 juillet 2018 Dernière intervention - 26 août 2008 à 23:58
0
Merci
Salut,

fait plutôt ça :

ImageIcon icon = new ImageIcon(...);
icon.getImage(); // pour t'assurer que l'image est bien chargée
//exploitation de l'objet ImageIcon

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 14:38
0
Merci
Merci, mais j'utilise déjà getImage(), étant de toute façon obligé d'employer un objet Image pour des fonctions comme
int, int, java.awt.image.ImageObserver) drawImage(Image img, int x, int y, ImageObserver observer)
Nitruk
Commenter la réponse de Nitruk
Twinuts 5270 Messages postés dimanche 4 mai 2003Date d'inscription 9 juillet 2018 Dernière intervention - 27 août 2008 à 14:48
0
Merci
Salut,

oui mais faiT le une première fois avant de l'utiliser dans la méthode drawImage, comme ça tu n'attendras pas *ce* moment là pour charger complètement l'image.

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 14:54
0
Merci
Erci encore mais je viens de le faire et ça ne change rien, d'ailleurs  le chargement commence bien avant puisque ma boucle m'envoyait des 8
(COMPLETE) avant de bloquer sur des 2 (ABORTED).

Nitruk
Commenter la réponse de Nitruk
Twinuts 5270 Messages postés dimanche 4 mai 2003Date d'inscription 9 juillet 2018 Dernière intervention - 27 août 2008 à 15:21
0
Merci
Salut,

oui mais la solution que je te propose ne doit pas avoir ta boucle ...

tien voici 3 exemples pour charger un image (exemple pour un SplashScreen) :

exemple 1 : Utilisation de ImageIcon et la méthode getImage
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Test extends JFrame {
   
    public Test() {
        setDefaultCloseOperation(3);
       
        //chargement de l'image
        ImageIcon icon = new ImageIcon("img.png");
        icon.getImage();
        // creation d'un label pour l'image
        JLabel content = new JLabel();
        content.setIcon(icon);
        //ajout du label à la fenetre
        setContentPane(content);

        pack();
        setLocationRelativeTo(null);
    }
   
    public static void main(String[] args) {
        new Test().setVisible(true);
    }

}

exemple 2 : Utilisation de ImageIcon et de la méthode read de l'objet ImageIO
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Test extends JFrame {
   
    public Test() {
        setDefaultCloseOperation(3);
       
        //chargement de l'image
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("img.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        ImageIcon icon = new ImageIcon(img);
        icon.getImage();
        // creation d'un label pour l'image
        JLabel content = new JLabel();
        content.setIcon(icon);
        //ajout du label à la fenetre
        setContentPane(content);

        pack();
        setLocationRelativeTo(null);
    }
   
    public static void main(String[] args) {
        new Test().setVisible(true);
    }

}

exemple 3 : Utilisation de Image et d'un MediaTracker

import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Test extends JFrame {
   
    public Test() {
        setDefaultCloseOperation(3);
       
        //chargement de l'image
        Image img = Toolkit.getDefaultToolkit().createImage("img.png");
        MediaTracker mt = new MediaTracker(this);
        mt.addImage(img, 0);
        try {
            mt.waitForAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       
        // creation d'un label pour l'image
        JLabel content = new JLabel();
        content.setIcon(new ImageIcon(img));
        //ajout du label à la fenetre
        setContentPane(content);

        pack();
        setLocationRelativeTo(null);
    }
   
    public static void main(String[] args) {
        new Test().setVisible(true);
    }

}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 15:53
0
Merci
La première solution est celle que j'utilisais jusque là, la deuxième fonctionne sans problème, sauf que je ne peux pas utiliser getClass().getClassLoader().getResource(add) (La méthode toString() me renvoie une adresse absolue de type file:/d:/Java/image.gif qui déclenche cette erreur quand elle est soumise au constructeur de File  :

javax.imageio.IIOException: Can't read input file!
        at javax.imageio.ImageIO.read(ImageIO.java:1275)
        at clientFen$1PanneauIcone.(clientFen.java:273
        at clientFen.(clientFen.java:311)
        at Client.main(Client.java:16)
Exception in thread "main" java.lang.NullPointerException
        at javax.swing.ImageIcon.(ImageIcon.java:161)
        at clientFen$1PanneauIcone.(clientFen.java:277
        at clientFen.(clientFen.java:311)
        at Client.main(Client.java:16)

Or mon programme prenant place dans un jar, j'ai besoin d'ne apsser par là. Je vais donc essayer la 3ème solution de ce pas.

Nitruk
Commenter la réponse de Nitruk
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 16:07
0
Merci
Je suis encore passé à deux doigts d'y arriver : Si le constructeur de File n'accepte aps ce type d'adresses, celui d'URI s'en accomode très bien, et on peut construire un File à partir d'un URI.
... Sauf que dans un jar, ma classe se met à émettre une erreur :

Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
        at java.io.File.(File.java:363)
        at clientFen$1PanneauIcone.(clientFen.java:272)
        at clientFen.(clientFen.java:331)
        at Client.main(Client.java:16)

Nitruk
Commenter la réponse de Nitruk
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 16:46
0
Merci
La 3ème solution donne le même résultat que la première, ce qui n'est aps surprenant, puisque le constructeur d'ImageIcon utilise le Media Tracker, donc en théorie devrait attendre d'avoir fini de charger l'image avant de rendre la main.
Je conclus donc à un bug du tracker, ce qui m'avance bien, avec URI qui ne fonctionne pas dans un jar..
Si quelqu'un a une meilleure idée, je serais ravi de l'entendre.
Merci d'avance

Nitruk
Commenter la réponse de Nitruk
Nitruk 128 Messages postés lundi 8 août 2005Date d'inscription 20 juillet 2009 Dernière intervention - 27 août 2008 à 18:38
0
Merci
Merci, cette fois ça marche. Apparement (d'après cette expérience et ce que j'ai pu voir sur les forums de Sun) mon problème serait lié à l'utilisation de fichiers dans un jar (Les fichiers temporaires doivent être créés dans le répertoire de la classe, et on ne peut pas directement créer un fichier dans un jar). Avec le getResourceasStream() j'ai les avantages de ImageIO.read()
 (mes images sont entièrement chargées avant l'apparition de la fenêtre) sans les inconvénients de File(URI) (Ca fonctionne dans un jar.)

Donc tout va bien, et merci encore !

Nitruk
Commenter la réponse de Nitruk

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.