Colorer des cellules d'un JTable Amaguiz [Résolu]

crjohnson 6 Messages postés lundi 17 novembre 2008Date d'inscription 12 juin 2009 Dernière intervention - 1 juin 2009 à 14:50 - Dernière réponse : crjohnson 6 Messages postés lundi 17 novembre 2008Date d'inscription 12 juin 2009 Dernière intervention
- 6 juin 2009 à 11:37
Salut les frères,

Je bûche sur ce prob' depuis ce matin et je parviens toujours pas à atteindre mon but. J'aimerais colorer le fond des cellules sélectionnées dans la JTable en fonction de la couleur choisie dans une JComboBox.

L'utilisateur devra sélectionner les cellules qu'il veut colorer et ensuite faire son choix dans la combobox à côté et une fois le choix fait les cellules sélectionnées prennent le fond de la couleur sélectionnée.

Le problème c'est que la coloration se fait bizarrement. Par exemple, quand je sélectionne la 1ère ligne, ça se passe normalement et si je sélectionne la dernière, toute la table prend la couleur. On dirait que les couleurs veulent pas laisser de cases avec coloration noire d'origine entre elles. Vous comprendrez mieux en testant ce code.

Je vous lache la partie pertinente du code et je vous serai reconnaissant de me filer un coup de main :

CLASSE "Fenetre" :

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

class Fenetre extends JFrame
{
    String[]   titres               = { "Composer" , "un" , "numéro" };
    Object[][] entrees              = {
                                      { "1" , "2"  , "3" },
                                      { "4" , "5"  , "6" },
                                      { "7" , "8"  , "9" },
                                      { " " , "0"  , " " },
                                      };
   
    DefaultTableModel modele = new DefaultTableModel(entrees, titres);
    JTable            table;
   
    JPanel     panneau_east         = new JPanel();
    JLabel       label_couleurs     = new JLabel("Colorier en :");
    JComboBox    combobox_couleurs  = new JComboBox();
   
    public Fenetre()
    {
        setTitle("*** T€$T ***");
        setSize(400, 200);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
       
        table = new JTable(modele)
        {
            public Component prepareRenderer(TableCellRenderer renderer, int ligne, int colonne)
            {
                Component component = super.prepareRenderer(renderer, ligne, colonne);

               

                // Je parie que c'est dans les conditions ci-dessous qu'il manque du matos.

               
                if(combobox_couleurs.getSelectedItem() == "Rouge")
                {
                    if(ligne == table.getSelectedRow())
                    { component.setBackground(Color.RED); }
                }
               
                if(combobox_couleurs.getSelectedItem() == "Vert")
                {
                    if(ligne == table.getSelectedRow())
                    { component.setBackground(Color.GREEN); }
                }
               
                if(combobox_couleurs.getSelectedItem() == "Bleu")
                {
                    if(ligne == table.getSelectedRow())
                    { component.setBackground(Color.BLUE); }
                }
               
                table.setBackground(Color.BLACK);
                table.setForeground(Color.WHITE);
               
                return component;
            }
        };
       
        combobox_couleurs.addItem("... Rien");
        combobox_couleurs.addItem("Rouge");
        combobox_couleurs.addItem("Vert");
        combobox_couleurs.addItem("Bleu");
       
        panneau_east.setLayout(new GridLayout(2, 1));
        panneau_east.add(label_couleurs);
        panneau_east.add(combobox_couleurs);
       
        getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
        getContentPane().add(panneau_east, BorderLayout.EAST);
    }
}

Pour lancer la bête :

CLASSE "Main" :

@SuppressWarnings("unused")
public class Main
{
    public static void main(String[] args)
    {
        Fenetre fenetre = new Fenetre();
    }
}

Merci les gens.
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
uhrand 493 Messages postés samedi 20 mai 2006Date d'inscription 15 juillet 2012 Dernière intervention - 6 juin 2009 à 04:35
3
Merci
Comme je l'ai déjà expliqué plus haut, le "rendererComponent" est un composant
unique qui est utilisé pour toutes les cellules de la table. C'est en quelque sorte un "tampon configurable". Puisque c'est un simple tampon, il ne sait pas mémoriser la configuration par ligne. Donc, dans la méthode "prepareRenderer" nous devons chaque fois reconfigurer le tampon.
L'utilisation de l'interface "Map" est très simple pour mémoriser les couleurs des lignes. P.ex. voici le code pour créer la colorMap:
Map colorMap = new HashMap();
Pour mémoriser une ligne avec couleur bleu: colorMap.put(ligne, Color.BLUE);
Pour avoir la bonne couleur dans notre méthode "prepareRenderer": colorMap.get(ligne)

Merci uhrand 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 126 internautes ce mois-ci

Commenter la réponse de uhrand
Meilleure réponse
crjohnson 6 Messages postés lundi 17 novembre 2008Date d'inscription 12 juin 2009 Dernière intervention - 6 juin 2009 à 11:37
3
Merci
Comment il s'est trop simplifié le code avec ta "colorMap" cousin tu m'as fait kiffer, on part en vacances !

Alors pour tous les chers collègues qui veulent colorier une table à leur guise, voici la solution pour les lignes :

Commence par déclarer une map de couleurs dans les attributs de ta classe, on le lache "private" pour respecter l'encapsulation :

private Map colorMap = new HashMap();

Après, tu déclares ta table en redéfinissant la méthode "prepareRenderer()" de la classe "DefaultTableModel" :

table = new JTable(new DefaultTableModel(entrees, titres))
{
    private static final long serialVersionUID = 1L;
   
    public Component prepareRenderer(TableCellRenderer renderer, int ligne, int colonne)
    {
        Component component = super.prepareRenderer(renderer, ligne, colonne);
        component.setBackground(colorMap.get(ligne));
        return component;
    }
};

Ensuite, tu peux faire un listener qui va écouter les clicks sur ta table :

table.addMouseListener(new MouseListener()
{
    public void mouseReleased(MouseEvent event)
    {
        if(combobox_couleurs.getSelectedItem() == "... Rien")
        { colorMap.put(table.getSelectedRow(), Color.WHITE); table.updateUI(); }
       
        if(combobox_couleurs.getSelectedItem() == "Rouge")
        { colorMap.put(table.getSelectedRow(), Color.RED); table.updateUI(); }
    }
   
    public void mouseEntered(MouseEvent event){}
    public void mouseExited(MouseEvent event){}
    public void mousePressed(MouseEvent event){}
    public void mouseClicked(MouseEvent event){}
});

Vaut mieux implémenter la méthode "mouseReleased()" parce que "mouseClicked" y a des fois ça réagit mal, je pense c'est à cause du temps.

Voilà les gars y a tous les éléments pour faire cette fameuse, tu sais j'ai lu plein de topics où des gens demandaient la même chose que moi et y avait que des soluces compliquées qui étaient proposées et en plus elles marchaient pas. Là t'as une soluce simple t'as même pas besoin de faire une nouvelle classe c'est ça la classe.

Grand merci à "uhrand" pour ses lumières.

Merci crjohnson 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 126 internautes ce mois-ci

Commenter la réponse de crjohnson
uhrand 493 Messages postés samedi 20 mai 2006Date d'inscription 15 juillet 2012 Dernière intervention - 1 juin 2009 à 16:01
0
Merci
Nous devons comprendre que le "rendererComponent" est un composant unique qui est utilisé pour toutes les cellules de la table. Si je peus dire,  il est utilisé comme un "tampon configurable" que le système tamponne sur chaque cellule. Prenons, comme dans ton exemple, la propriété "background" du "tampon". Dans ton exemple, cette propriété est bien configurée pour trois types de cellules: rouge, vert et bleu. Puisqu'il y a qu'un seul "tampon", toutes les autres cellules auront alors la propriété "background" qui est configurée par hasard pour un des trois types! Donc, ce qu'il faut faire, c'est d'initialiser la propriété "background" par une couleur de défaut, avant de procéder aux cas spécifiques. Exemple:
// Je parie que c'est dans les conditions ci-dessous qu'il manque du matos.
component.setBackground(table.getBackground()); // initialiser la propriété "background"
//cas spécifiques (rouge, vert, bleu):
...
Commenter la réponse de uhrand
crjohnson 6 Messages postés lundi 17 novembre 2008Date d'inscription 12 juin 2009 Dernière intervention - 1 juin 2009 à 16:22
0
Merci
Ah voilà c'est la fameuse "mémo" de fond de table que je cherchais, merci fréro. Mais il reste un problème : ça fonctionne pas.

Par exemple, en choisissant rouge je sélectionne la ligne 1, pas de soucis, ensuite je sélectionne la ligne 3, elle se remplit de rouge mais la ligne 1 est retournée au noir, idem en changeant de couleur.

Je crois que c'est parce que la fonction "getBackground()" de "JTable" retourne un "Color", ce qui signifie que ça donnera une seule couleur : le noir d'origine qu'on a défini : "table.setBackground(Color.BLACK);". En fait faudrait trouver une fonction qui permette de mémoriser la couleur de chaque cellule du tableau quand on l'appelle à un instant "t", mais quelle est-elle... J'ai pensé à un "ColorModel" mais je vois pas comment m'y prendre.

Encore merci.
Commenter la réponse de crjohnson
uhrand 493 Messages postés samedi 20 mai 2006Date d'inscription 15 juillet 2012 Dernière intervention - 3 juin 2009 à 21:32
0
Merci
Effectivement, tu as encore un autre problème: tu détermine le type de la ligne sur base de la combobox_couleurs, ce qui ne peut pas fonctionner, car la combobox_couleurs ne contient pas de référence à une ligne. Nous pouvons par exemple utiliser une Map pour stocker la couleur par ligne ou définir une classe qui représente une ligne et y stocker la couleur, ...
Le stockage pour la ligne sélectionnée peut se faire déjà dans le traitement de la combobox_couleurs (p.ex. dans un ActionListener attaché à la combobox_couleurs). Puis, dans "prepareRenderer" nous exploitant la "colorMap" ou l'objet reprsésentant la ligne...
Commenter la réponse de uhrand
crjohnson 6 Messages postés lundi 17 novembre 2008Date d'inscription 12 juin 2009 Dernière intervention - 5 juin 2009 à 23:08
0
Merci
Fada frère j'arrive pas à comprendre ce foutu objet JTable... et l'objet Map j'ai beau lire des articles à ce sujet je sais toujours pas m'en servir.

J'aimerais simplement que tous les fonds de toutes les cellules de la ligne sélectionnée se colorent en une couleur spécifique, quite à en définir une par défaut pour les tests. Au click sur une autre ligne, on fait la même chose mais en gardant en mémoire l'opération précédente, etc. Et au pire, sélectionner toutes les lignes à colorier, sélectionner la couleur dans la combo' et appuyer sur le champignon pour les remplir, mais ce que j'arrive pas à faire c'est MEMORISER le fond. Si je fais des trucs genre "else setBackground(Color.WHITE);" je perds la mémo' et si je le fais pas y a trop de lignes qui se remplissent alors j'suis coincé fréro. Si un gadjo qui a déjà été dans cette galère passe par là il peut lacher tout son code sérieux moi je me démerde pour retrouver les pièces de l'engin.

Merci de l'aide, on va gagner Mr. Saint-Josse...
Commenter la réponse de crjohnson

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.