IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

Couleur du texte d'une cellule particulière


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Par défaut Couleur du texte d'une cellule particulière
    Bonjour,

    J'ai une interface java qui utilise un JTable et j'aimerais changer la couleur de fond d'une cellule particulière, ayant accès à la table JTable, et connaissant la ligne et la colonne à modifier.

    J'ai trouvé plein de codes qui utilisent un super (au sens génial :p) getTableCellRendererComponent pour accéder à setForeground(), mais sans aucun succès...

    A vrai dire, la classe qui doit modifier la cellule est un Thread lancé par clic sur un bouton du tableau.
    Dans ce processus, j'ai accès à la ligne et la colonne à modifier, ainsi qu'à l'élément JTable sur lequel faire les modifs (celui-ci étant global).

    Par exemple dans ce cas, j'utilise la commande suivante pour changer la valeur de la cellule :
    Tools.JButtonTableExample.table.setValueAt(nouvelle_valeur, ligne, colonne);

    Comment changer de façon aussi intuitive que ça la couleur du texte ?
    Ou du fond de la cellule si c'est plus facile...


    Par avance, merci.

  2. #2
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Salut,

    En créant une Map dans ton renderer par exemple. Cette map prendra un objet coordonnee en clé et une couleur en valeur. Il suffit d'alimenter la map, puis lors du rendu, de chercher la couleur dans la map qui correspond à la cellule évaluée (row et column) dans le renderer. S'il la trouve on l'utilise, sinon on utilise une couleur par défaut.

    L'avantage est que tu définit une couleur pour n'importe qu'elle cellule (mais en général on le fait en fonction des données, donc je ne voit pas trop l'interrêt de ce que tu demande).
    L'inconvénient est que ta map doit être à jour.
    Et si tu as 10000 lignes dans ta Jtable, je ne sais pas si c'est très performant

    Si tu veux uniquement changer la couleur d'une seule cellule, alors la map est inutile. Tu n'as qu'a la remplacer dans MonRenderer par deux int représentant la ligne et la colonne de la cellule, ce qui est plus simple et efficace.

    Ca fonctionne, mais il y a peut-être mieux à faire.
    Voici un exemple (vite écrit) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.HashMap;
    import java.util.Map;
    import javax.swing.BoxLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
     
    public class MyJTable {
     
    	private static MonRenderer renderer = new MonRenderer();
     
    	public static void main(String[] args) {
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		Object[][] donnees = {
    				{ "Swing", "Astral", "standard", Color.red, Boolean.TRUE },
    				{ "Swing", "Mistral", "standard", Color.yellow, Boolean.FALSE },
    				{ "Gin", "Oasis", "standard", Color.blue, Boolean.FALSE },
    				{ "Gin", "boomerang", "compétition", Color.green, Boolean.TRUE },
    				{ "Advance", "Omega", "performance", Color.cyan, Boolean.TRUE }, };
    		String[] titreColonnes = { "marque", "modèle", "homologation",
    				"couleur", "vérifiée ?" };
    		final JTable table = new JTable(donnees, titreColonnes);
    		table.setDefaultRenderer(Object.class, renderer);
     
    		JButton btn = new JButton("add RED to Coordonnee(1,1)");
    		btn.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				renderer.add(new Coordonnee(1, 1), Color.RED);
    				table.repaint();
    			}
    		});
    		JButton btn2 = new JButton("add MAGENTA to Coordonnee(2,3)");
    		btn2.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				renderer.add(new Coordonnee(2, 3), Color.MAGENTA);
    				table.repaint();
    			}
    		});
     
    		JPanel panel = new JPanel();
    		BoxLayout l = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
    		panel.setLayout(l);
    		panel.add(btn);
    		panel.add(btn2);
    		panel.add(new JScrollPane(table));
    		frame.setContentPane(panel);
    		frame.pack();
    		frame.setVisible(true);
    	}
     
    	private static class Coordonnee {
     
    		private int x;
    		private int y;
     
    		public Coordonnee(int x, int y) {
    			this.x = x;
    			this.y = y;
    		}
     
    		public int getY() {
    			return this.y;
    		}
     
    		public void setY(int y) {
    			this.y = y;
    		}
     
    		public int getX() {
    			return this.x;
    		}
     
    		@Override
    		public boolean equals(Object obj) {
    			if (obj instanceof Coordonnee) {
    				Coordonnee c = (Coordonnee) obj;
    				if (this.x == c.x && this.y == c.y) {
    					return true;
    				}
    			}
    			return false;
    		}
     
    		@Override
    		public int hashCode() {
    			return (String.valueOf(this.x) + String.valueOf(this.y)).hashCode();
    		}
     
    	}
     
    	@SuppressWarnings("serial")
    	private static class MonRenderer extends DefaultTableCellRenderer {
     
    		private final static Color DEFAULT_COLOR = Color.BLACK;
     
    		private Map<Coordonnee, Color> map;
     
    		public MonRenderer() {
    			this.map = new HashMap<Coordonnee, Color>();
    		}
     
    		public void add(Coordonnee cd, Color c) {
    			this.map.put(cd, c);
    		}
     
    		public void remove(Coordonnee cd) {
    			this.map.remove(cd);
    		}
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
    			super.getTableCellRendererComponent(table, value, isSelected,
    					hasFocus, row, column);
     
    			Color c = this.map.get(new Coordonnee(column, row));
    			if (c == null) {
    				c = DEFAULT_COLOR;
    			}
    			setForeground(c);
     
    			return this;
    		}
     
    	}
     
    }

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Par défaut
    Bonjour et merci pour votre réponse,

    Effectivement, la couleur que je veux changer est fonction des données.
    Et je ne veux changer la couleur d'une seule cellule à la fois.

    En gros j'ai un tableau avec deux colonnes : un champ de texte et un bouton.
    Lorsque je clique sur le bouton d'une ligne donnée, ça lance un thread en fond qui fait des calculs dépendant de cette ligne, et change le texte de la première colonne.
    Je voudrais aussi que ça change la couleur de ce même texte.

    Donc chaque thread lancé en cliquant sur le bouton ne modifie qu'une cellule particulière de cette même ligne.
    Je ne pense pas que le Hash soit le mieux dans ce cas, n'est-ce pas ?

    J'ai pas très bien compris comment changer le Renderer par deux int, mais je regarderai ce soir (je suis au boulot là...).

    Et aussi je débute en interfaces java...
    En tout cas merci pour votre réponse.

  4. #4
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Citation Envoyé par $p00ky Voir le message
    Effectivement, la couleur que je veux changer est fonction des données
    Alors je t'avais mal compris...
    Dans ce cas, pas besoin de ce gourbis. Un Renderer classique suffit.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Par défaut
    Edit : réponse trouvée (nouveau problème levé dans le message suivant)

    Et la question est maintenant de comment accéder à ce Renderer, car getTableCellRendererComponent prend en paramètres beaucoup trop de variables à mon goût...

    Moi je voudrais juste accéder au Renderer de ma cellule particulière et changer son Foreground.
    getTableCellRendererComponent prend aussi le tableau, la valeur, hasFocus et isSelected en paramètres...
    J'ai fait quelques essais, mais ca n'a jamais changé ce que je voulais ! Ca change souvent beaucoup trop de lignes (lignes entières, même pas uniquement cellules...).

    Je voudrais juste à la fin de mon Thread, sur le même principe que je change la valeur de la cellule (simplement table.setValueAt(nouvelle_valeur, ligne, colonne)) changer la couleur de ce texte.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Par défaut
    Oh, j'ai compris !
    (désolé je débute en GUI...)

    En fait il me suffit de définir le TableCellRenderer() de cette colonne.

    Par exemple, un petit test qui affiche en rouge si supérieur à 20, en vert sinon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class HomeMadeTextRenderer extends JLabel implements TableCellRenderer {
     
    	public HomeMadeTextRenderer() {
     
    	}
     
    	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    		if (NumberUtils.isNumber(value.toString().replace(",",""))) {
    			if (Integer.parseInt(value.toString().replace(",","")) > 20) {
    			      setForeground(Color.red);
    		    } else {
    		      setForeground(Color.green);
    		    }
    		}
    		else {
    			setForeground(Color.black);
    		}
     
    	    setText((value == null) ? "" : value.toString());
    	    return this;
    	}
    }
    Et ensuite lorsque je crée ma colonne, de la définir comme utilisant ce modèle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table.getColumn("Ma_colonne").setCellRenderer(new HomeMadeTextRenderer());
    Ca marche très bien, mais le seul petit hic est que j'ai perdu le "surlignage" de la ligne en faisant ça :s et le texte est maintenant en gras dans cette colonne...
    Avant lorsque je cliquais sur une cellule de la ligne, toute la ligne se mettait en "sélectionnée".
    Maintenant toute la ligne SAUF la cellule de ma colonne avec le "HomeMadeTextRenderer" est sélectionnée...

    J'ai essayé de jouer avec le "hasFocus" et "setSelected" mais sans réussite...
    Et pour le gras aucune idée...
    Qu'est-ce qui m'échappe ?

  7. #7
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    DefaultTableCellRenderer est en fait un JLabel. Il n'y en a qu'un, qui sera utilisé par toutes les celulles pour une raison d'optimisation.

    isSelected permet de savoir si la cellule est sélecitonné. Tu peut alors utiliser les méthodes table.getSelectionForeground() et setBackground(table.getSelectionBackground()) pour rétablir la sélection.

    De plus tu peut avoir un renderer par type d'objet. Cela ce définis dans la méthode table.setDefaultRenderer(Object.class, renderer). Dans ce cas comme tout objet est un Objet, cela s'appliquera à tout. Mais tu peux être plus restrictif. Mias tu devra alors définir ton propre model hériter de AbstractTableModel. C'est simple. Tu redéfini alors en autre la méthode getColumnClass de façon a ce que les renderer puisse identifier le type de classe auxquels il ont été attribuer.

    Voici un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.BoxLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableCellRenderer;
     
    public class MyJTable {
     
    	public static void main(String[] args) {
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		Object[][] donnees = {
    				{ "Swing", "Astral", new Integer(20), Color.red, Boolean.TRUE },
    				{ "Swing", "Mistral", new Integer(5), Color.yellow,
    						Boolean.FALSE },
    				{ "Gin", "Oasis", new Integer(2), Color.blue, Boolean.FALSE },
    				{ "Gin", "boomerang", new Integer(28), Color.green,
    						Boolean.TRUE },
    				{ "Advance", "Omega", new Integer(10), Color.cyan, Boolean.TRUE }, };
    		String[] titreColonnes = { "marque", "modèle", "Quantité", "couleur",
    				"vérifiée ?" };
    		MonModele model = new MonModele(donnees, titreColonnes);
    		final JTable table = new JTable(model);
    		table.setDefaultRenderer(Integer.class, new MonRendererInteger());
    		table.setDefaultRenderer(Color.class, new MonRendererColor());
     
    		JPanel panel = new JPanel();
    		BoxLayout l = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
    		panel.setLayout(l);
    		panel.add(new JScrollPane(table));
    		frame.setContentPane(panel);
    		frame.pack();
    		frame.setVisible(true);
    	}
     
    	@SuppressWarnings("serial")
    	private static class MonModele extends AbstractTableModel {
     
    		private Object donnees[][];
    		private String titres[];
     
    		public MonModele(Object donnees[][], String titres[]) {
    			this.donnees = donnees;
    			this.titres = titres;
    		}
     
    		@Override
    		public int getColumnCount() {
    			return this.donnees[0].length;
    		}
     
    		@Override
    		public Object getValueAt(int parm1, int parm2) {
    			return this.donnees[parm1][parm2];
    		}
     
    		@Override
    		public int getRowCount() {
    			return this.donnees.length;
    		}
     
    		@Override
    		public String getColumnName(int col) {
    			return this.titres[col];
    		}
     
    		@Override
    		public Class<?> getColumnClass(int columnIndex) {
    			if (columnIndex == 0 || columnIndex == 1) {
    				return String.class;
    			} else if (columnIndex == 2) {
    				return Integer.class;
    			} else if (columnIndex == 3) {
    				return Color.class;
    			} else {
    				return Boolean.class;
    			}
    		}
     
    	}
     
    	@SuppressWarnings("serial")
    	private static class MonRendererInteger extends DefaultTableCellRenderer {
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
    			super.getTableCellRendererComponent(table, value, isSelected,
    					hasFocus, row, column);
     
    			if (value instanceof Integer) {
    				System.out.println("integer");
    				Integer integer = (Integer) value;
    				if (isSelected) {
    					setForeground(table.getSelectionForeground());
    					setBackground(table.getSelectionBackground());
    				} else {
    					if (integer.intValue() > 10) {
    						setForeground(Color.RED.darker());
    						setBackground(Color.PINK);
    					} else {
    						setForeground(Color.BLACK);
    						setBackground(Color.WHITE);
    					}
    				}
    			}
     
    			return this;
    		}
     
    	}
     
    	@SuppressWarnings("serial")
    	private static class MonRendererColor extends DefaultTableCellRenderer {
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
    			super.getTableCellRendererComponent(table, value, isSelected,
    					hasFocus, row, column);
     
    			if (value instanceof Color) {
    				Color color = (Color) value;
    				if (isSelected) {
    					setForeground(table.getSelectionForeground());
    					setBackground(table.getSelectionBackground());
    				} else {
    					setBackground(color);
    				}
    				setText("");
    			}
     
    			return this;
    		}
     
    	}
     
    }

Discussions similaires

  1. Couleur de texte d'une cellule avec POI
    Par chrime71 dans le forum API standards et tierces
    Réponses: 0
    Dernier message: 22/07/2010, 17h06
  2. Modifier la couleur du texte dans une cellule StringGrid
    Par Jotomaticen dans le forum C++Builder
    Réponses: 3
    Dernier message: 22/09/2009, 22h42
  3. [XL-2007] Utiliser plusieurs couleurs au texte d'une cellule avec vba
    Par CRC dans le forum Excel
    Réponses: 2
    Dernier message: 21/08/2009, 14h37
  4. Réponses: 4
    Dernier message: 21/01/2009, 08h15
  5. Modifier la couleur du texte d'une cellule d'un tableviewer.
    Par tatemilio2 dans le forum SWT/JFace
    Réponses: 4
    Dernier message: 27/06/2008, 08h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo