Image dans ComboBox

Résolu
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013 - 10 nov. 2011 à 08:15
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013 - 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

11 réponses

cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 nov. 2011 à 12:14
;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)
3
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 nov. 2011 à 09:10
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)
0
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013
10 nov. 2011 à 11:41
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 !
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 nov. 2011 à 12:23
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)
0

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

Posez votre question
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 nov. 2011 à 16:19
on! ben tu ne dois plus avoir de problémes!!! ;o)


GodConan ;o)
0
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013
10 nov. 2011 à 21:03
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
0
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013
14 nov. 2011 à 10:51
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 ...
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
14 nov. 2011 à 18:24
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)
0
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013
14 nov. 2011 à 19:41
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
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
14 nov. 2011 à 19:53
;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)
0
paesmarc Messages postés 24 Date d'inscription mercredi 6 mai 2009 Statut Membre Dernière intervention 22 août 2013
14 nov. 2011 à 20:08
OK, merci pour tout.
Marc
0
Rejoignez-nous