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 :

Ajouter un ascenseur vertical dans les cellules de l'entête de la JTable


Sujet :

Composants Java

  1. #1
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut Ajouter un ascenseur vertical dans les cellules de l'entête de la JTable
    bonjour,

    il arrive que les titres des colonnes de ma JTable ne tiennent pas dans la cellule. Pour y remédier, je souhaite ajouter des ascenseurs dans ces cellules. Pour cela, j'ai créé un cellRenderer que j'applique au JTableHeader :
    Code java : 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
     
    public class TestHeaderRenderer extends DefaultTableCellRenderer
    {
        private Dimension dim = new Dimension();
     
        public TestHeaderRenderer()
        {
            setHorizontalAlignment(CENTER);
            //setVerticalAlignment(CENTER);
            setVerticalAlignment(TOP);
        }
     
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column)
        {
            JTableHeader header;
     
            JScrollPane scrollPane = new JScrollPane();
     
            header = table.getTableHeader();
     
            //this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
     
            this.setOpaque(true);
            this.setForeground(header.getForeground());
            this.setBackground(header.getBackground());
            this.setFont(header.getFont());
     
            dim.height = Constants.HEADER_HEIGHT;//table.getRowHeight();
            dim.width = header.getColumnModel().getColumn(column).getWidth();
            this.setPreferredSize(dim);
     
            this.setText("<html><center>" + (String)value + "</center></html>");
     
            this.setEnabled(true);
            scrollPane.setEnabled(true);
            scrollPane.setWheelScrollingEnabled(false);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
            scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            scrollPane.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
            scrollPane.setViewportView(this);
            scrollPane.setPreferredSize(dim);
     
            return scrollPane;
        }
    }

    J'instancie mon cellRenderer de cette manière :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.table.getTableHeader().setDefaultRenderer(new TestHeaderRenderer() );

    Le problème est que mes ascenseurs sont inactifs (voir la copie d'écran)
    Il ne doit pas manquer grand chose pour que cela fonctionne. Comment faire ?

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Tu ferais mieux d'utiliser du HTML, la hauteur du Header s'accorder automatiquement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String myHeaderText1="<html><b>Hello<br>world</b></html>";
    De plus le comportement que tu as remarqué est tout à fait normal.

    Les renderers ne sont pas de composants, il ne gèrent aucune interaction avec l'utilisateur. Il servent juste à dessiner l'apparence d'un composant sur une cellule. Donc pas de gestion des events....

    Pour toi la façon d'y remédier serait d'avoir un ensemble de listeners placés sur le header et de forwarder ça au renderer... Et encore, il faudrait trouver un moyen de séparer les JScrollPane, car pour le moment, un seul JScrollPane est utilisé pour l'ensemble des cellules...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  3. #3
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par sinok Voir le message
    Tu ferais mieux d'utiliser du HTML, la hauteur du Header s'accorder automatiquement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String myHeaderText1="<html><b>Hello<br>world</b></html>";
    c'est ce que j'ai fait. L'inconvénient du HTML est que je perds le centrage vertical dans le composant



    Citation Envoyé par sinok Voir le message
    De plus le comportement que tu as remarqué est tout à fait normal.

    Les renderers ne sont pas de composants, il ne gèrent aucune interaction avec l'utilisateur. Il servent juste à dessiner l'apparence d'un composant sur une cellule. Donc pas de gestion des events....

    Pour toi la façon d'y remédier serait d'avoir un ensemble de listeners placés sur le header et de forwarder ça au renderer... Et encore, il faudrait trouver un moyen de séparer les JScrollPane, car pour le moment, un seul JScrollPane est utilisé pour l'ensemble des cellules...
    C'est la description d'un CellEditor ? Je me trompe ?

    Je me suis inspiré de ce code (3ème message). Il fonctionne très bien pour des cellules qui ne sont pas dans l'entête. Pour les cellules de l'entête cela ne fonctionne pas. Les titres de colonnes auraient une particularité que les autres cellules d'une table n'ont pas ?

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Bah, tu as toujours les balises center...

    Attention, toutefois, l'alignement du header varie selon le look & feel. Le look & feel par défaut (métal) met le texte au centre. Par contre, le look & feel windows le met à gauche pour rester raccord avec la façon de faire de windows...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  5. #5
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par sinok Voir le message
    Bah, tu as toujours les balises center...

    J'ai fait un peu plus compliqué : j'utilise le HTML lorsque la chaine dépasse la longueur de la cellule et je modifie également le centrage vertical (le centrage vertical est ignoré avec le HTML) :
    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
     
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column)
        {
            JTableHeader header;
            int n;
     
            header = table.getTableHeader();
     
            this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
     
            this.setOpaque(true);
            this.setForeground(header.getForeground());
            this.setBackground(header.getBackground());
            this.setFont(header.getFont());
     
            dim.height = 35;
            dim.width = header.getColumnModel().getColumn(column).getWidth();
            this.setPreferredSize(dim); 
     
            n = header.getFontMetrics(this.getFont()).stringWidth((String)value);
     
            intercellSpacing = table.getIntercellSpacing();              
     
            if (n > dim.width-intercellSpacing.getWidth()*4)
            {
                setVerticalAlignment(TOP);
                this.setText("<html><center>" + (String)value + "</center></html>");
            }
            else
            {
                setVerticalAlignment(CENTER);
                this.setText((String)value);
            }
     
            return this;
        }

    Citation Envoyé par sinok Voir le message
    Attention, toutefois, l'alignement du header varie selon le look & feel. Le look & feel par défaut (métal) met le texte au centre. Par contre, le look & feel windows le met à gauche pour rester raccord avec la façon de faire de windows...
    oui j'ai vu ça. Avec le L&F Metal et le L&F Windows pas de souci cela fonctionne.
    Par contre avec le L&F Liquid (proche de mac), le style n'est pas appliqué, même la hauteur des lignes est ignorée. Mais ce n'est pas trop grave


    Mais pour revenir un peu plus sur le problème :
    Citation Envoyé par Auteur
    Je me suis inspiré de ce code (3ème message). Il fonctionne très bien pour des cellules qui ne sont pas dans l'entête. Pour les cellules de l'entête cela ne fonctionne pas. Les titres de colonnes auraient une particularité que les autres cellules d'une table n'ont pas ?

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    POur faire simple, le header n'a pas d'editor...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  7. #7
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par sinok Voir le message
    POur faire simple, le header n'a pas d'editor...
    bon dans ce cas, je mets la discussion résolu.

    Mes connaissances en java n'étant pas très grandes, je me vois mal partir dans la conception de la classe que tu m'as décrite plus haut :
    Citation Envoyé par sinok
    Pour toi la façon d'y remédier serait d'avoir un ensemble de listeners placés sur le header et de forwarder ça au renderer... Et encore, il faudrait trouver un moyen de séparer les JScrollPane, car pour le moment, un seul JScrollPane est utilisé pour l'ensemble des cellules...
    Surtout que l'utilité ne serait pas très grande.
    Tant pis



    NB : j'ai vu que le sujet avait été vu plus de 700 fois en 2 jours . Je ne serai pas le seul à essayer d'implémenter une telle fonctionnalité ??

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/08/2011, 08h37
  2. ajouter des combobox dans les cellules de stringgrid
    Par sky88 dans le forum Débuter
    Réponses: 5
    Dernier message: 22/01/2009, 18h35
  3. jvftweek ajout dans les cellules
    Par Mihalis dans le forum Delphi
    Réponses: 1
    Dernier message: 17/03/2007, 18h54
  4. [JTable] centrer les donnees dans les cellules
    Par cmoa59 dans le forum Composants
    Réponses: 5
    Dernier message: 20/05/2005, 11h35
  5. Alignement dans les cellules d'un tableau
    Par philippef dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 23/02/2005, 12h15

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