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 :

DefaultTableCellRenderer et problème d'"imbrication"


Sujet :

Composants Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Juin 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2018
    Messages : 7
    Points : 6
    Points
    6
    Par défaut DefaultTableCellRenderer et problème d'"imbrication"
    Bonjour,
    Nouveau sur ce site, et débutant dans la POO, en particulier Java, je me tourne vers vous afin de vous demandez une petite aide sur un petit problème que je rencontre et qui, je suis sûr, a une solution simple. Tout cela dans le cadre d'une auto-formation. En fait, avant de détailler, mon problème se situe sur une "sorte" d'imbrication de DefaultTableCellRenderer. Mais avant tout, mon code va en faire sans doute hurler plus d'un, mais on a tous été débutant, non ?
    En effet, j'ai une classe ProprietesLigneTable qui permet de définir la police, les bordures des cellules et la couleur des lignes. Elle marche bien et je la donne ci-dessous :
    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
     
    public class ProprietesLigneTable 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);
            setFont(new Font("Lucida Console", Font.PLAIN, 13));
            setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            if ((row & 1) == 0) {                    // Ligne paire
                setBackground(Color.LIGHT_GRAY);
            } else {                                 // Ligne impaire
                setBackground(Color.WHITE);
            }
            return this;
        }
    }
    Cette classe est mise en oeuvre dans une méthode (d'une autre classe) de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    TableColumn col;
    table.setRowHeight(28);
    ProprietesLigneTable pct=new ProprietesLigneTable();
    for (int i=0;i<=nbColonnes;i++) {
                table.getColumnModel().getColumn(i).setCellRenderer(pct);
                col = table.getColumnModel().getColumn(i);
                if(table.getModel().getColumnName(i).equals("Compte")) {
                // Là je fais quelques traitements du style :
                    col.setMinWidth(87);
                    col.setMaxWidth
    Tout ça marche bien. En fait, pour résumer cette méthode, elle donne des tailles fixes aux colonnes et ces tailles sont fonction de la longueur de la source. Est-ce dans la philosophie Java, je ne sais pas, mais là n'est pas encore mon problème.
    En glanant sur Internet, j'ai trouvé aussi la façon de centrer le contenu dans une colonne, et le code suivant marche bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            DefaultTableCellRenderer custom =  new DefaultTableCellRenderer(); 
            custom.setHorizontalAlignment(JLabel.CENTER); // centre les données de ton tableau
            col.setCellRenderer(custom); // avec col=col = table.getColumnModel().getColumn(i);
    Mais si on reprend ma méthode ci-dessus et qu'on fait :
    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
     
    // Propriétés des lignes.
     
            DefaultTableCellRenderer custom =  new DefaultTableCellRenderer(); 
            custom.setHorizontalAlignment(JLabel.CENTER); // centre les données de ton tableau
     
            TableColumn col;
            table.setRowHeight(28);
            ProprietesLigneTable pct=new ProprietesLigneTable();
            for (int i=0;i<=nbColonnes;i++) {
                table.getColumnModel().getColumn(i).setCellRenderer(pct);
                col = table.getColumnModel().getColumn(i);
                if(table.getModel().getColumnName(i).equals("Compte")) {
                    //col.setPreferredWidth(87);
                    col.setMinWidth(87);
                    col.setMaxWidth(87);
                } else if(table.getModel().getColumnName(i).equals("Date")) {
                    //col.setPreferredWidth(87);
                    col.setMinWidth(87);
                    col.setMaxWidth(87);
                    col.setCellRenderer(custom);
    la colonne perd toutes les propriétés mises en œuvre par l'instanciation de ProprietesLigneTable(). En fait j'ai soit l'un, soit l'autre, mais pas les deux.
    Je ne sais pas si j'ai été très clair. Il me semble que dans ma classe ProprietesLigneTable() j'utilise DefaultTableCellRenderer mais que comme dans ma méthode j'en instancie un autre, le premier n'est plus d'actualité.
    Et ma question est donc : comment faire pour appliquer mon setCellRenderer(custom).
    Je vous remercie beaucoup,
    Aldrik.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Citation Envoyé par Aldrik Voir le message
    Et ma question est donc : comment faire pour appliquer mon setCellRenderer(custom).
    Tu ne dois tout simplement pas.

    Pour centrer le contenu de la colonne, on t'a donné cet exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DefaultTableCellRenderer custom =  new DefaultTableCellRenderer(); 
            custom.setHorizontalAlignment(JLabel.CENTER); // centre les données de ton tableau
    et indiquer qu'il fallait "appliquer custom", c'est-à-dire une instance de DefaultTableCellRender telle qu'on a centrer le texte (ce qu'on peut faire parce que DefaultTableCellRenderer étend JLabel qui se centre par cette méthode.

    Tu ne peux bien sûr pas appliquer 2 TableCellRenderer à la même colonne : le second remplace le précédent. Mais comme ta classe ProprietesLigneTable étend DefaultTableCellRenderer, tu peux utiliser le même moyen pour centrer le texte dans une colonne rendue par ProprietesLigneTable. Tout simplement en faisant par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TableColumn col;
    table.setRowHeight(28);
    ProprietesLigneTable pct=new ProprietesLigneTable();
    pct.setHorizontalAlignment(JLabel.CENTER);
    for (int i=0;i<=nbColonnes;i++) {
    /**...**/
    Tu peux même faire :
    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
    public class ProprietesLigneTable extends DefaultTableCellRenderer {
     
        public ProprietesLigneTable() {
            super();
            setHorizontalAlignment(JLabel.CENTER)
        }
     
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            setFont(new Font("Lucida Console", Font.PLAIN, 13));
            setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            if ((row & 1) == 0) {                    // Ligne paire
                setBackground(Color.LIGHT_GRAY);
            } else {                                 // Ligne impaire
                setBackground(Color.WHITE);
            }
            return this;
        }
    }
    Plus besoin, ainsi de l’appeler dans le code d'affectation ci-dessus.

    Tu devrais en revanche éviter de créer une instance de Font à chaque rendu de cellule. La même instance peut être utilisée (une private static final par exemple). Normalement, le principe c'est d'affecter la police à la JTable (le renderer la reprendra automatiquement), mais c'est vrai qu'elle sera également appliquée aux entêtes, ce que tu ne veux peut-être pas.

    Attention, par ailleurs à ton implémentation des couleurs de lignes paires/impaires : tu perds la couleur indiquant qu'une ligne est sélectionnée... Il existe une notion dans Swing pour gérer ça : Table.alternateRowColor. Il s'agit d'une propriété globale pour toutes les tables, mais ça t'éviterait d'avoir à gérer toi-même tout ça.

    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
     
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.UIDefaults;
    import javax.swing.UIManager;
     
    public class JTableRowDemos {
     
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		String[] cols = {"Col 1","Col 2", "Col 3"};
    		Object[][] data = new Object[10][cols.length];
    		for(Object[] lines : data) {
    			for(int i=0; i<lines.length; i++) {
    				lines[i]=(i+1)*10;
    			}
    		}
     
     
    		UIDefaults defaults = UIManager.getDefaults();
    		defaults.put("Table.alternateRowColor",  defaults.getColor("Panel.background")); // en utilisant la couleur de fond par défaut
    		//defaults.put("Table.alternateRowColor",  new ColorUIResource(Color.LIGHT_GRAY)); // en indiquant la couleur de son choix
     
    		JTable table = new JTable(data, cols);
     
    		frame.add(new JScrollPane(table));
     
    		frame.setSize(600,300);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
     
    	}
     
    }


    De la même façon, tu peux avoir un problème avec la notion de rendu pour le focus, si ta table est éditable.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Juin 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2018
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup. Tes conseils sont les bienvenus. Par contre la solution proposée (la n°1) marche TROP bien, car toutes les colonnes sont impactées. Or je ne cherche à centrer que certaines colonnes comme ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                } else if(table.getModel().getColumnName(i).equals("Note")) {
                    //col.setPreferredWidth(168);
                    col.setMinWidth(168);
                    col.setMaxWidth(168);
                } else if(table.getModel().getColumnName(i).equals("Statut")) {
                    //col.setPreferredWidth(55);
                    col.setMinWidth(55);
                    col.setMaxWidth(55);
                    pct.setHorizontalAlignment(JLabel.CENTER);
                }
    Mais le fait d'appliquer pct.setHorizontalAlignment(JLabel.CENTER); sur la colonne "Statut" le fait implicitement sur toutes les autres. Ce que je ne veux pas.
    Merci encore

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Il te faut deux instances de ProprietesLigneTable, une centrée, une pas centrée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ProprietesLigneTable pct=new ProprietesLigneTable();
    ProprietesLigneTable pctCentered=new ProprietesLigneTable();
    pctCentered.setHorizontalAlignment(JLabel.CENTER);
    Et tu affectes l'une ou l'autre aux colonnes voulues.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (int i=0;i<table.getColumnCount();i++) {
                TableColumn col = table.getColumnModel().getColumn(i);
                switch(table.getColumnName(i)) {
                case "Note":
                case "Statut":
                     // colonnes centrées
                     col.setCellRenderer(pctCentered);
                     break;
                default:
                     col.setCellRenderer(pct);
                }
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Juin 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2018
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Mille fois merci joel.drigo.
    Ça marche.
    Java, Swing et la POO ont encore beaucoup de mystères pour moi, bien que j'aie beaucoup fait de conception Objet (OOA méthode Shlaer et Mellor), méthode qui a disparu avec UML.
    En tous les cas un grand merci.
    Je vais appliquer tes autres conseils. Je ferme le post.
    Bonne soirée.

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

Discussions similaires

  1. [Wamp] Problème d'insertion avec quote d'un formulaire
    Par cyberdevelopment dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 20/08/2006, 18h55
  2. [SQL-Server] Problèmes de guillemets et quotes dans un INSERT
    Par gregb34 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/05/2006, 09h40

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