Image dans ComboBox [Résolu]

paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 10 nov. 2011 à 08:15 - Dernière réponse : paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention
- 14 nov. 2011 à 20:08
Bonjour,
J'aimerais mettre une image + texte dans une ComboBox (Une seule image à coté du premier texte (indice 0)).
J'ai utilisé le code repris ici et ça fonctionne chez moi.
Mais dès que je souhaite implémenter ce code pour ma ComboBox, je rencontre plusieurs problèmes. Le plus récurrent est : 'Exception in thread "main" java.lang.NullPointerException
at renderer.ComboBoxRenderer.getListCellRendererComponent' qui concerne la ligne 'int selectedIndex = ((Integer)value).intValue();' pour la méthode 'getListCellRendererComponent()'.
Voici le code de la méthode de la class GUI:
private JComboBox getJComboBoxClientsList() {
if (jComboBoxClientsList == null) {
CustomComboBox newContentPane = new CustomComboBox();
ComboBoxRenderer renderer = new ComboBoxRenderer(newContentPane.getImages(), newContentPane.getPetStrings());
jComboBoxClientsList = new JComboBox(newContentPane.getIntArray());
jComboBoxClientsList.setRenderer(renderer);
jComboBoxClientsList.setMaximumSize(jComboBoxClientsList.getPreferredSize());
jComboBoxClientsList.addActionListener(ccb);
}
return jComboBoxClientsList;
}

Ensuite, la classe que j'ai nommée 'ComboBoxRenderer':
public class ComboBoxRenderer extends JLabel implements ListCellRenderer {
ImageIcon[] images;
    String[] petStrings = {"Bird", "Cat", "Dog", "Rabbit", "Pig"};
    private Font uhOhFont;
 
public ComboBoxRenderer(ImageIcon[] images,  String[] petStrings) {
setOpaque(true);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
this.images = images;
this.petStrings = petStrings;
}
 
/*
* This method finds the image and text corresponding
* to the selected value and returns the label, set up
* to display the text and image.
*/
public Component getListCellRendererComponent(
                JList list,
                Object value,
                int index,
                boolean isSelected,
                boolean cellHasFocus) {
//Get the selected index. (The index param isn't
//always valid, so just use the value.)
int selectedIndex = ((Integer)value).intValue();
 
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
 
//Set the icon and text.  If icon was null, say so.
ImageIcon icon = images[selectedIndex];
String pet = petStrings[selectedIndex];
setIcon(icon);
if (icon != null) {
setText(pet);
setFont(list.getFont());
} else {
setUhOhText(pet + " (no image available)",
 list.getFont());
}
 
return this;
}
 
//Set the font and text when no image was found.
protected void setUhOhText(String uhOhText, Font normalFont) {
if (uhOhFont == null) { //lazily create this font
uhOhFont = normalFont.deriveFont(Font.ITALIC);
}
setFont(uhOhFont);
setText(uhOhText);
}
} 

Et pour finir, la class que j'ai nommée 'CustomComboBox':
public class CustomComboBox extends JPanel {
    ImageIcon[] images;
    String[] petStrings = {"Bird", "Cat", "Dog", "Rabbit", "Pig"};
    Integer[] intArray = new Integer[petStrings.length];
 
    /*
     * Despite its use of EmptyBorder, this panel makes a fine content
     * pane because the empty border just increases the panel's size
     * and is "painted" on top of the panel's normal background.  In
     * other words, the JPanel fills its entire background if it's
     * opaque (which it is by default); adding a border doesn't change
     * that.
     */
    public CustomComboBox() {
        super(new BorderLayout());
 
        //Load the pet images and create an array of indexes.
        images = new ImageIcon[petStrings.length];
        Integer[] intArray = new Integer[petStrings.length];
        for (int i = 0; i < petStrings.length; i++) {
            intArray[i] = new Integer(i);
            images[0] = new ImageIcon(ClassLoader.getSystemResource("images/48x48/dualScreen.png"));
            if (images[i] != null) {
                images[i].setDescription(petStrings[i]);
            }
        }
    }
 
    // GETTES-----------------------
 
public ImageIcon[] getImages() {
return images;
}
 
public String[] getPetStrings() {
return petStrings;
}
 
public Integer[] getIntArray() {
return intArray;
}
 
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
 
}  
     

Est-ce que quelqu'un peut m'aider ?
Merci d'avance.
Marc
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 10 nov. 2011 à 12:14
3
Merci
;o) tu as fais une erreur de visibilité ;o) ...
ton tableau d Integer n est pas initialisé... chacun des membre est à null ...

code corrigé...

public class CustomComboBox extends JPanel {
    ImageIcon[] images;
    String[] petStrings = {"Bird", "Cat", "Dog", "Rabbit", "Pig"};
// ca il vaut mieu évité, cela t urai permi de voir de suite ton erreur
//    Integer[] intArray = new Integer[petStrings.length];
    Integer[] intArray = null;
 
    public CustomComboBox() {
        super(new BorderLayout());
 
        //Load the pet images and create an array of indexes.
        images = new ImageIcon[petStrings.length];
// ----------- l erreur etait la ------
//Integer[] intArray = new Integer[petStrings.length];
        intArray = new Integer[petStrings.length];
        for (int i = 0; i < petStrings.length; i++) {
            intArray[i] = new Integer(i);
            images[0] = new ImageIcon(ClassLoader.getSystemResource("images/48x48/dualScreen.png"));
            if (images[i] != null) {
                images[i].setDescription(petStrings[i]);
            }
        }
    }
 
    // GETTES-----------------------
 
public ImageIcon[] getImages() {
return images;
}
 
public String[] getPetStrings() {
return petStrings;
}
 
public Integer[] getIntArray() {
return intArray;
}
 
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
 
} 

GodConan ;o)

Merci cs_GodConan 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 117 internautes ce mois-ci

Commenter la réponse de cs_GodConan
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 10 nov. 2011 à 09:10
0
Merci
salut

si tu as ce message c est que value doit surement etre à null
un petit traitement du style : if (value!=null) { ton code utilisant value}else{ faut quand meme que renderer fasse un rendu ;o) }

GodConan ;o)
Commenter la réponse de cs_GodConan
paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 10 nov. 2011 à 11:41
0
Merci
Merci pour ton aide mais le problème est de savoir pourquoi il est null (d'où ça vient) car dans le code initial (ici), ça ne cause pas de problème !
Commenter la réponse de paesmarc
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 10 nov. 2011 à 12:23
0
Merci
ceci dit ;o) il serait plus interressant de prendre toute les informations necessaire au rendu dans 'value' en faisant par exemple une class Data{ String label ="";ImageIcon icon = null; /*(et les methode associé )*/} et pourquoi pas d autre attributs ;o)

ensuite ne te reste plus qu a passer des Data ou lieu d Integer à ta Combobox ;o) ainsi ;o) ton renderer tu peux le nommmer DataComboRenderer par exemple ;o)

de plus dans le code de ton cellRenderer 'selectedIndex' est inutil ;o) puisque tu dispose de 'index'

GodConan ;o)
Commenter la réponse de cs_GodConan
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 10 nov. 2011 à 16:19
0
Merci
on! ben tu ne dois plus avoir de problémes!!! ;o)


GodConan ;o)
Commenter la réponse de cs_GodConan
paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 10 nov. 2011 à 21:03
0
Merci
Me revoilà
Super, je n'ai plus ce problème (heureusement qu'il y a encore des pros comme vous ).
Mais je n'obtiens tjrs pas le résultat souhaité. Je vais voir où est le problème et quand ça fonctionnera, j'essayerai d'implémenter ta solution de class Data...
Encore merci.
Marc
Commenter la réponse de paesmarc
paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 14 nov. 2011 à 10:51
0
Merci
Bonjour GodConan,

J'ai essayé d'impléménter ta solution mais j'éprouve quelques difficultés. En fait, je ne comprends pas bien la méthode getListCellRendererComponent() !
De plus, quand je supprime 'selectedIndex', comme tu me l'as conseillé, et que j'utilise 'index', celui-ci me rend -1.
Donc, si je comprends bien, je ne sais utiliser que le paramètre value ...
Commenter la réponse de paesmarc
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 14 nov. 2011 à 18:24
0
Merci
c est étonnant qu il te rende -1!! ... mais ce n est pas abérant ;o) ... fautdrai que je refasse des test !! me rapelle plus trop du comportement exact de la class ;o) ...

getListCellRendererComponent() ;o) c est tout le charme des java swing ;o) ... En gros toutes les class nécéssitant un rendu (ou plutot, devant faire le rendu de données) on besoin d 1 model de donnée et d 1 renderer ;o)
ici on parle du renderer : la methode getListCellRendererComponent() est appelé par la combo pour déléguer le rendu de chacun element de sa liste... ;o) évidement il y en a toujours un par defaut ;o) et souvent on herite une class graphique (JLabel par exemple) qui implement l interface utile (ListCellRenderer par exemeple) et on renvoi this (soit une instance de JLabel customized) ;o) et c est carrement magique... ;o) tu peux faire des renderer dépendant du Composant ... et tout un tas de chose exotique ... ;o) en lisant les sources du java on comprend bien ces comportements ;o) ... et donc la methode getcomponent est appeler par le composant quand il doit se charger de son rendu ;o)

ensuite la dificulter c est de savoir à quel moment ;o) cette methode est appelé ;o) ... durant les 3 derniere version ca a un peu changé (en bien) cependant cela oblige quand meme parfoi à prendre en compte certain cas particulier dans l implementation de la methode ou de la class ;o) ... fais des essais ;o) tu veras c est sympa, surcharge paintComponents de ta class renderer ;o) (pour voir ) et appelle ou non la methode super ;o)



GodConan ;o)
Commenter la réponse de cs_GodConan
paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 14 nov. 2011 à 19:41
0
Merci
Oulala, j'ai presque l'impression que tu me parles chinois !
Merci pour tes conseils, je vais lire ça à tête reposée ...
J'ai suivi des cours de java (mais pas bcp d'expérience) mais j'ai pas vos connaissances, comment faites-vous pour comprendre/connaître tout ça ???
Marc
Commenter la réponse de paesmarc
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 14 nov. 2011 à 19:53
0
Merci
;o) ... bcp de lectures ... bcp de temps ... bcp de test ;o)
Et l enorme aventage du JAVA c est que le source de toute les class est disponible ;o) très bonne façon d aprendre que de le lire... ;o) , il m arrive encore de le faire de temps à autre ;o) pour vérifier le comportement d un composant ;o) ...

Je n ai jamais suivis de cours java ;o) ... ce n ai pas vraiment utile, il faut surtout apprehender la POO ...

GodConan ;o)
Commenter la réponse de cs_GodConan
paesmarc 24 Messages postés mercredi 6 mai 2009Date d'inscription 22 août 2013 Dernière intervention - 14 nov. 2011 à 20:08
0
Merci
OK, merci pour tout.
Marc
Commenter la réponse de paesmarc

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.