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 :

[JTable] ajout d'un bouton dans une colonne


Sujet :

Composants Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut [JTable] ajout d'un bouton dans une colonne
    Bonjour,

    J ai regarder pas mal de poste sur le forum concernant l'ajout d'objet graphique dans une cellule du tableau, mais j ai pas compris grand chose, et les méthodes me paraissent un peu complexe.

    Voici mon code actuelle (chargement d'element ds une liste chainée)

    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
     
    public void chargement(CListe listenonsuperviser, CListe listesuperviser)
    {
    	 int taillnsp=listenonsuperviser.size();
    	 taille=((listenonsuperviser.size())+(listesuperviser.size()));
    	 int nb=0;
    	 for&#40;int i=0; i<jTconf.getRowCount&#40;&#41;; i++&#41; // vidage du tableau
    	 	&#123; for&#40;int j=0; j<4; j++&#41;
                      jTconf.setValueAt&#40;"",i,j&#41;;  &#125;
    	 for&#40;int i=0;i<taillnsp;i++&#41; // chargement de la liste des postes non superviser
    	 &#123;
    		 int colonne=0;
    		 pc =&#40;CControle_agent_snmp&#41;listenonsuperviser.get&#40;i&#41;;
    		 String nomposte = pc.getNom_poste&#40;&#41;;
    		 jTconf.setValueAt&#40;nomposte,i,colonne++&#41;;
    		 String adressip = pc.getAdresse_ip&#40;&#41;;
    		 jTconf.setValueAt&#40;adressip,i,colonne++&#41;;
    		 jTconf.setValueAt&#40;new Integer&#40;pc.getNum_port&#40;&#41;&#41;,i,colonne++&#41;;
    		 jTconf.setValueAt&#40;new Integer&#40;pc.getSupervision&#40;&#41;&#41;,i,colonne++&#41;;
     
    // je souhaiterai faire un jTconf.setValue&#40;jButton,i,colonne++&#41;	 
    &#125;
    	 for&#40;int a=taillnsp;a<taille;a++&#41; //chargement sur le tableau de la liste des postes superviser
    	 &#123;
    		 int col=0;
    		 pc =&#40;CControle_agent_snmp&#41;listesuperviser.get&#40;nb&#41;;
    		 String nomposte = pc.getNom_poste&#40;&#41;;
    		 jTconf.setValueAt&#40;nomposte,a,col++&#41;;
    		 String adressip = pc.getAdresse_ip&#40;&#41;;
    		 jTconf.setValueAt&#40;adressip,a,col++&#41;;
    		 jTconf.setValueAt&#40;new Integer&#40;pc.getNum_port&#40;&#41;&#41;,a,col++&#41;;
    		 jTconf.setValueAt&#40;new Integer&#40;pc.getSupervision&#40;&#41;&#41;,a,col++&#41;;
    		 nb++;
    	 &#125;&#125;
    Je souhaiterai ajouter un bouton pour chaque élement du tableau, et bien sur pouvoir effectuer une action sur ce bouton, mais je ne peux pas modifier le code actuel. Ce que je souhaite faire est-il possible sans modifier le code déja présent. Si oui quel est la méthode à suivre etc.

    Merci de votre aide.

  2. #2
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Bonjour,
    il y a une différence entre le contenu des cellules et la manière de l'afficher. Autrement dit, mettre un JButton dans la case d'un JTable ne lui fera pas forcément afficher un JButton.

    C'est le renderer qui construit le composant graphique qui représentera les cellules de la JTable.

    Faire un JButton est un peu plus compliqué que de mettre du texte simple, mais pour clarifier les choses, tu devras faire quelque chose qui ressemble à ça :
    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
    public class ButtonCellRenderer extends JButton implements TableCellRenderer, ActionListener &#123;
     
      public ButtonCellRenderer&#40;&#41; &#123;
        this.addActionListener&#40;this&#41;;
      &#125;
     
      //methode destinee a implementer TableCellRenderer
      // Elle définit comment paramétrer le JButton en fonction
      // du contenu de la cellule et de si on l'a sélectionné ou non
      public Component getTableCellRendererComponent&#40;JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column&#41; &#123;
     
        this.setText&#40;value.toString&#40;&#41;&#41;;
        // ajouter quelques mises en couleur en fonction de si la case
        // est sélectionnée ou non, ou a le focus.
     
        this.setActionCommand&#40;String.valueOf&#40;row&#41; + ";" + String.valueOf&#40;column&#41;&#41;; // par exemple.
     
        return this;
      &#125;
     
      //methode destinee a implementer ActionListener
      // Elle sera appelée à chaque fois qu'on clique sur un quelconque bouton
      // de la Table
      public void actionPerformed&#40;ActionEvent e&#41; &#123;
     
        System.out.println&#40;"Vous avez cliqué sur le bouton &#58; " + e.getSource&#40;&#41;.getText&#40;&#41;&#41;;
     
        String&#91;&#93; coordonnees = e.getActionCommand&#40;&#41;.split&#40;";"&#41;;
        int row = Integer.parseInt&#40;coordonnees&#91;0&#93;&#41;;
        int column = Integer.parseInt&#40;coordonnees&#91;1&#93;&#41;;
     
        System.out.println&#40;"Il est situé à la case &#58;" + row + " " + column&#41;;
      &#125;
    Enfin, pour l'utiliser, il suffit d'appeler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TableCellRenderer monRenderer = new ButtonCellRenderer&#40;&#41;;
    maJTable.setDefaultRenderer&#40;monRenderer&#41;;
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    Le fait d'utiliser ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TableCellRenderer monRenderer = new ButtonCellRenderer&#40;&#41;; 
    maJTable.setDefaultRenderer&#40;monRenderer&#41;;
    Me permettra d'avoir un button que dans un seul colonne? ou alors juste de creer un button, que je dois appeller apres avec la methode setValueAt(Object, int row,int col)?



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public Component getTableCellRendererComponent&#40;JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column&#41; &#123; 
     
        this.setText&#40;value.toString&#40;&#41;&#41;; 
        // ajouter quelques mises en couleur en fonction de si la case 
        // est sélectionnée ou non, ou a le focus. 
     
        this.setActionCommand&#40;String.valueOf&#40;row&#41; + ";" + String.valueOf&#40;column&#41;&#41;; // par exemple. 
     
        return this; 
      &#125;
    A quoi correspond l'objet value?
    Plus tard je voudrais que mon boutton est 2 état Superviser et Arreter. Je veux dire que l'une fois que l'on a cliquer sur Arreter, le text du button change et passe en Superviser, l action effectué sera differente ( je sais coder ceci). Mais est ce que je dois definir ces choses dans cette parti de code?
    Merci pour tous

  4. #4
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Bon, après réflexion, ton idée de mettre directement les JButton dans la table est assez géniale ! Donc oublie le code que j'ai donné avant, il complique les choses pour rien.

    Je t'explique un peu plus en détail le principe des renderer, et je te propose une solution simple :

    - le code que j'ai posté mettra automatiquement un bouton dans toutes les cases.

    - lorsque tu mets l'objet nomposte de type String dans la cellule (3, 5), la JTable appelle la méthode getTableCellRendererComponent en lui passant comme paramètres :
    • - table = elle-même
      - value = la String nomposte
      - isSelected = true si la case est sélectionnée, false sinon
      - hasFocus = true si la case a le focus, false sinon
      - row = 3 (numéro de ligne)
      - column = 5 (numéro de colonne)
    Et elle affiche le composant retourné.

    Solution simple

    Tu as l'air de tenir à ajouter un JButton dans une case (et ça va simplifier les choses). Ce que tu peux faire, c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class ButtonOrDefaultCellRenderer extends DefaultTableCellRenderer &#123;
      public Component getTableCellRendererComponent&#40;JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column&#41; &#123;
     
        if&#40;value instanceof JButton&#41;
          return &#40;JButton&#41;value;
     
        return super.getTableCellRendererComponent&#40;table, value, isSelected, hasFocus, row, column&#41;;
      &#125;
    Comme ça, si tu utilises ce renderer, tu peux mettre un JButton dans une case, il l'affichera. Sinon, il se comportera normalement.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     return super.getTableCellRendererComponent&#40;table, value, isSelected, hasFocus, row, column&#41;;
    Il n y aurai pas une erreur car un setTableCellRenderer doit avoir comme parametre (Class, TableCellEditor)


    Une fois que j ai redefini le TableCellRenderer, j'initialise avec ce nouveau TableCellRenderer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    TableCellRenderer monrenderer = new tablebutton&#40;&#41;;
    jTconf.setDefaultRenderer&#40;monrenderer&#41;; // meme probleme manque un parametre
    Mais apres le probleme c'est comment appeller l'objet avec le SetValueAt?

  6. #6
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Il n y aurai pas une erreur car un setTableCellRenderer doit avoir comme parametre (Class, TableCellEditor)
    Tiens, c'est vrai, c'est nouveau, ça ! Tu programmes donc en version 1.5. Il suffit de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setDefaultRenderer&#40;Object.class, monRenderer&#41;;
    Bon, j'étais sûr de mon coup, mais je viens de tester la classe, et les boutons ne réagissent pas lorsque je clique dessus ! Il y a comme un problème.

    La seule solution que je vois, c'est de passer par l'editor, mais il existe peut etre mieux. Je teste.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  7. #7
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Je ne sais pas comment faire. Quelqu'un a une idée ?
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  8. #8
    Membre éprouvé Avatar de leminipouce
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2004
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2004
    Messages : 754
    Points : 1 253
    Points
    1 253
    Par défaut
    Oui !

    Et parce que je suis gentil, je la donne

    Je précie quand même qu'elle me déplait un peu et qu'elle peu surement être améliorée, mais ça marchouille. Mon plus gros soucis c'est qu'il faut double cliquer pour effectuer l'action. En fait l'éditor ne s'active qu'après un clic. Mais ça fait parti des spécif. de Sun. Dès que j'ai un peu de temps je rends le code plus beau et surtout je trouve un moyen d'éviter ce double-clique.

    Bref la solution que je mets en oeuvre consiste à ajouter non pas un JButton dans la table, mais un JPanel. Ensuite libre à toi de mettre ce que tu veux dans le panel.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class ViewButtonPanel extends JPanel
    {
        public ViewButtonPanel(MainFrame parent)
        {
            super();
     
            this.add(parent.newButton(Constants.VIEW));
            this.setVisible(true);
        }
    }
    Avec la méthode newButton() suivante :
    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
    /**
         * Creates a new button named with the given text. Register this button to the ButtonListener.
         * 
         * @param text
         *            the JButton label.
         * 
         * @return the button label with the given text, registered to the ButtonListener.
         */
        public JButton newButton(String text)
        {
            JButton newButton = new JButton(text);
            newButton.addMouseListener(getButtonsListener());
            newButton.setVisible(true);
     
            return newButton;
        }
    et la signature suivante pour mon ButtonsListener :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class ButtonsListener implements MouseListener
    Ensuite je fais la déclaration suivante dans mon MainFrame :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JTable valueTable = new JTable();
    puis j'ai le code suivant qui me permet de mettre à jour ma table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public void updateValueTable()
        {
            if (isEditingModel() && !valueTable.getModel().equals(myModel))
            {
                valueTable.setModel(myModel);
                valueTable.setRowHeight(32);
     
                valueTable.setDefaultRenderer(ViewButtonPanel.class, new ViewButtonPanelRenderer(this));
                valueTable.setDefaultEditor(ViewButtonPanel.class, new ViewButtonPanelEditor(this));
            }
     
            ((myModel) valueTable.getModel()).update();
        }
    La méthode updateValueTable() est appelée par le listener de mes boutons (ButtonsListener). Ma table peut changer complètement d'aspect selon le bouton sur lequel on clique.

    La méthode update de mon modèle permet de mettre à jour les données affichées (je vous passe les accès BD)...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void update()
        {
            // Update data (SQL query)...
     
            // Update column names (if necessary)
            this.fireTableStructureChanged();
            // this.fireTableChanged(new TableModelEvent(this));
            this.fireTableDataChanged();
        }
    Et sa méthode getValueAt(int row, int col) peut évidement renvoyer un ViewButtonPanel :
    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
    public Object getValueAt(int row, int col)
        {
            Object columnValue = "";
     
            switch (col)
            {
                //...
     
                case 3:
                    columnValue = new ViewButtonPanel(mainFrame);
                    break;
     
                default:
                    break;
            }
     
            return columnValue;
        }
    Et pour conclure, voici mon Renderer et mon Editor :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class ViewButtonPanelRenderer extends DefaultTableCellRenderer
    {
        private ViewButtonPanel viewButtonPanel = null;
     
        public ViewButtonPanelRenderer(MainFrame parent) {
            viewButtonPanel = new ViewButtonPanel(parent);
        }
     
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean focusable, int row, int col)
        {
            return viewButtonPanel;
        }
    }
    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
    public class ViewButtonPanelEditor extends AbstractCellEditor implements TableCellEditor
    {
        private ViewButtonPanel viewButtonPanel = null;
     
        public ViewButtonPanelEditor(MainFrame parent) {
            viewButtonPanel = new ViewButtonPanel(parent);
        }
     
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
                int row, int col)
        {
            return viewButtonPanel;
        }
     
        public Object getCellEditorValue()
        {
            return viewButtonPanel;
        }
    }
    Voilà.

    C'est pas forcément trivial, mais j'ai tenu à tout séparer (Model, Contenu de cellule, Renderer, Editor...). Ca me permet une plus grande souplesse d'utilisation (mettre autant de Render et d'Editor que je veux !!!), même si c'est un peu plus chiant à coder.
    Si , et la ont échoué mais pas nous, pensez à dire et cliquez sur . Merci !

    Ici, c'est un forum, pas une foire. Il y a de respectables règles... à respecter !

Discussions similaires

  1. Réponses: 6
    Dernier message: 24/05/2014, 12h36
  2. [ext js 3.4] Ajouter un bouton dans une colonne d'un tableau
    Par pitou26 dans le forum Ext JS / Sencha
    Réponses: 1
    Dernier message: 07/11/2012, 13h15
  3. Ajout d'un bouton dans une feuille excel avec vba
    Par nsqualli dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 25/11/2008, 15h35
  4. [DataGridViewButtonColumn] Bouton dans une colonne avec une image
    Par aurelien.tournier dans le forum Windows Forms
    Réponses: 1
    Dernier message: 19/11/2007, 11h35
  5. JTable : comment insérer un bouton dans une cellule ?
    Par donyas dans le forum Composants
    Réponses: 2
    Dernier message: 08/08/2006, 15h54

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