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

Composants Java Discussion :

[DefaultCellRenderer] La couleur Foreground persiste sur les autres cellules


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Par défaut [DefaultCellRenderer] La couleur Foreground persiste sur les autres cellules
    Bonjour à tous !

    J'ai un souci avec mon cell renderer.
    J'ai deux JTable disposées côte à côte, tous les items de la JTable de gauche sont contiennent une collection et c'est cette collection qui s'affiche dans la JTable de droite lorsqu'un item de la JTable de gauche est sélectionné.

    J'ai besoin de colorer le texte de certaines colonnes de la JTable de droite en vert ou rouge si la colonne contient une donnée (le choix entre rouge ou vert se fait en fonction du contenu), si elle ne contient pas de donnée je laisse la case vide.

    Le problème est qu'en réalité les cellules sont (et seront) de la même couleur que celle utilisée pour l'affichage de la première cellule dessinée par mon renderer.

    Exemple :
    L'item 1 contient un élément qui n'affiche rien dans les colonnes "colorées"
    L'item 2 contient un élément qui affiche une valeur rouge dans la première colonne et une valeur verte dans la seconde colonne.

    Au chargement de ma JFrame aucune donnée n'est affichée dans ma jtable de droite.

    Maintenant lorsque j'arrive sur cette JFrame et que je clique sur l'item 2 le texte des deux colonnes colorées est rouge (alors que seul le texte de la première devrait l'être, le texte de la seconde devant être coloré en vert).

    Plus "drôle" encore : si maintenant je sélectionne la ligne, le texte de la seconde colonne s'affiche bien en vert. Si je dé-sélectionne la ligne, le texte redevient rouge.

    Si je refais la manip en sélectionnant d'abord l'item 1 (qui n'affiche pas de données dans les colonnes "colorées") et qu'ensuite je sélectionne l'item 2 les deux colonnes ne sont ni rouges ni vertes, mais noires (couleur de texte classique, donc).
    Si je sélectionne la ligne je vois les bonnes couleurs derrière la sélection.

    J'imagine bien que c'est un problème lié au JLabel du renderer qui est dupliqué partout mais après plusieurs tentatives infructueuses j'en viens à vous demander de l'aide.

    Voici le code de mon Renderer :
    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
     
    public class DatePassageRenderer extends DefaultTableCellRenderer{
    	DateFormat formatter;
     
    	public DatePassageRenderer() {
    		super();
    	}
     
    	public void setValue(Object value) {
    		super.setValue(value);
     
    		setForeground(UIManager.getColor("Table.foreground"));
     
    		if(formatter == null) {
    			formatter = new SimpleDateFormat("EEEE d/MM/yyyy");
    		}
     
    		if(value != null) {
    			DatePassage dp = (DatePassage) value;
    			if(dp.getDate() != null) {
    				setText(formatter.format(dp.getDate()));
    				if(dp.getLate() != null) {
    					if(dp.getLate()) {
    						setForeground(Color.RED);
    					}
    					else {
    						setForeground(Color.GREEN);
    					}
    				}
    			}
    			else {
    				setText("");
    				setForeground(UIManager.getColor("Table.foreground"));
    			}
    		}		 
    	}
    }
    DatePassage étant un petit objet composé d'une date et d'un booléen.
    Le booléen indique s'il y a un retard ou non (si retard le texte passe en rouge sinon il est affiché en vert).

    Je vous remercie d'avance pour votre aide et reste à votre disposition pour toute éventuelle question.

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Commences d'abord par redéfinir getTableCellRendererComponent en lieu et place de setValue qui n'est pas franchement faite pour faire la config de l'UI.

    Puis penses à affecter systématiquement la couleur par défaut dès le début de la méthode getTableCellRendererComponent.

  3. #3
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Par défaut
    Toujours le même problème.

    J'ai interverti le setForeground() avec le super.getTableCellRendererComponent() et même commenté ce dernier (juste pour voir) et le résultat est identique.

    Voici le code :

    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
     
    public class DatePassageRenderer extends DefaultTableCellRenderer{
    	DateFormat formatter;
     
    	public DatePassageRenderer() {
    		super();
    	}
     
     
     
    	@Override
    	public Component getTableCellRendererComponent(JTable table, Object value,
    			boolean isSelected, boolean hasFocus, int row, int column) {
     
    		setForeground(UIManager.getColor("Table.foreground"));
     
    		super.getTableCellRendererComponent(table, value, isSelected, hasFocus,	row, column);		
     
     
     
    		if(formatter == null) {
    			formatter = new SimpleDateFormat("EEEE d/MM/yyyy");
    		}
     
    		if(value != null) {
    			DatePassage dp = (DatePassage) value;
    			if(dp.getDate() != null) {
    				setText(formatter.format(dp.getDate()));
    				if(dp.getLate() != null) {
    					if(dp.getLate()) {
    						setForeground(Color.RED);
    					}
    					else {
    						setForeground(Color.GREEN);
    					}
    				}
    			}
    			else {
    				setText("");
    			}
    		}
     
    		return this;
    	}
    }
    J'utilise une JXTable de chez SwingLabs et si je met une JTable à la place celà fonctionne bien.
    Le souci viendrait donc de la JXTable

  4. #4
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Vu que tu utilises une JXtable, il est préférable d'utiliser les mécanismes mis en place par Swingx au niveau des renderers. En effet il ne faut plus coder des renderers mais des classes héritant de ComponentProvider qui sont par la suite fournies au DefaultTableRenderer de Swingx.

    Cf le sujet suivant où il est question de JXTreeTable (ce qui revient au même qu'une JTable).
    http://www.developpez.net/forums/d90...table-jbutton/

  5. #5
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Par défaut
    Merci pour ta réponse sinok.

    J'ai creusé du côté de ComponentProvider et j'ai créé une classe qui hérite de LabelProvider dont voici le code :

    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
    public class DatePassageComponentProvider extends LabelProvider{
    	private DateFormat formatter;
     
    	public DatePassageComponentProvider() {
    		super();
     
    		formatter = new SimpleDateFormat("EEEE d/MM/yyyy à HH:mm");
    		StringValue sv = new StringValue() {
     
    			@Override
    			public String getString(Object obj) {
    				if(obj != null) {
    					if(obj instanceof DatePassage) {
    						DatePassage dp = (DatePassage) obj;
    						if(dp.getDate() != null) {
    							return formatter.format(dp.getDate());
    						}
    					}
    				}
     
    				return null;
    			}
    		};
     
    		setStringValue(sv);
    	}
     
    	@Override
    	protected void configureVisuals(CellContext context) {
    		super.configureVisuals(context);
     
    		if(context.getValue() != null) {
    			DatePassage dp = (DatePassage) context.getValue();
     
    			if(dp.getDate() != null) {
    				if(dp.getLate() != null) {
    					//Si retard : Affichage de la cellule en rouge
    					if(dp.getLate()) {
    						getDefaultVisuals().setForeground(Color.RED);
    						System.out.println("Column "+context.getColumn()+" is RED. Etape : "+dp.getEtape());
    					}
    					//Sinon en vert
    					else {
    						getDefaultVisuals().setForeground(Color.GREEN);
    						System.out.println("Column "+context.getColumn()+" is GREEN Etape : "+dp.getEtape());
    					}
    				}
    			}
    		}
    	}	
    }
    Il y a 4 étapes en tout mais seules 3 sont visibles sans scroller.
    Je me suis arrangé pour que la première soit en retard et pas les autres (donc la première colonne rouge et les autres vertes).
    Ce qui est corroboré par mon affichage console :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Colum 3 is RED. Etape : 1
    Colum 4 is GREEN Etape : 2
    Colum 5 is GREEN Etape : 3
    Colum 6 is GREEN Etape : 4
    Mais absolument pas par mon résultat visuel (capture jointe)

    Je ne connaissais pas du tout ce mécanisme propre à SwingX donc je me suis basé sur tes conseils donné sur le topic que tu as passé en lien et sur la javadoc de SwingX.

    Ce que j'ai fait me semble pourtant logique, mais bon
    Images attachées Images attachées  

  6. #6
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Devops
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Par défaut
    J'ai, à priori, résolu le problème.

    Quitte à utiliser les mécanismes internes à SwingX je suis passé aux Highlighter qui permettent ce genre de choses.
    Je pensais qu'un Highlighter s'occupait d'une ligne entière mais au final c'est assez modulable et je ne l'ai restreint qu'aux colonnes affichant des DatePassage.

    Merci pour votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 11/12/2006, 11h34
  2. Jpanels les un sur les autres avec Matisse (Netbeans)
    Par vallica dans le forum Composants
    Réponses: 13
    Dernier message: 28/11/2005, 22h19
  3. Réponses: 6
    Dernier message: 15/06/2004, 10h26
  4. Réponses: 17
    Dernier message: 15/10/2003, 01h45

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