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 de JRadioButtons, regroupés par rangée


Sujet :

Composants Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut JTable de JRadioButtons, regroupés par rangée
    Bonjour.
    Je n'ai pas trouvé de "Short, Self Contained, Correct(, Compilable), Example" de JTable dont les cellules des rangées contiennent, dans quelques colonnes contigües, des JRadioButton et dont les groupes correspondent aux rangées. Je tente donc de le réaliser moi-même, mais ça coince quelque part. Y a-t-il un connaisseur en la matière qui puisse me conseiller ? Il s'agit quand même d'une fonction qui devrait intéresser quelques programmeurs en Java.
    Voici d'abord mon code, en 4 fichiers, qui fonctionne à moitié :
    1) TableTest
    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
    /* But : 
     * Un tableau de p. ex. 5 colonnes de cases contenant chacune un bouton-poussoir.
     * Les boutons-poussoirs sont regroupée et interagissent par rangée entière de la table.
     * Pas d'autre type d'élément dans chaque rangée et pas de rangée contenant un autre type 
     * d'élément.
     */
    package test_table;
     
    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.AbstractCellEditor;
    import javax.swing.JFrame;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;     // main()
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
     
     
    public class TestTable
    {
        private JFrame cadre;
        private JTable table;
     
     
        protected void initUI()
        {
            table = new JTable(new MonModèleTable());
            short nbreColo = (short) table.getColumnCount();
            table.setRowHeight(25);
            TableColumn col;
     
            for (int i = 0 ; i < nbreColo ; i++)
            {
                col = table.getColumnModel().getColumn(i);
                col.setCellEditor  (new RendeurEditeur_CelluleBoutonRadio());
                col.setCellRenderer(new RendeurEditeur_CelluleBoutonRadio());
            }
     
            cadre = new JFrame();
            cadre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            cadre.add(new JScrollPane(table), BorderLayout.CENTER);
            cadre.pack();
            cadre.setVisible(true);
        }
     
     
        /**
         * @param args the command line arguments
         * @throws ClassNotFoundException
         * @throws InstantiationException
         * @throws IllegalAccessException
         * @throws UnsupportedLookAndFeelException
         */
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, 
                                                IllegalAccessException, UnsupportedLookAndFeelException
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override public void run()     // Implements method from java.lang.Runnable
                {
                    new TestTable().initUI();
                }
            }                       );
        }
     
     
        private class RendeurEditeur_CelluleBoutonRadio extends AbstractCellEditor
                implements TableCellRenderer, TableCellEditor, ActionListener
        {
            private final JRadioButton radioButton;
     
            public RendeurEditeur_CelluleBoutonRadio()
            {
                this.radioButton = new JRadioButton();
                radioButton.addActionListener(this);
                radioButton.setOpaque(false);
            }
     
     
            @Override public Component getTableCellRendererComponent(JTable table, Object valeur, 
                                        boolean estSélectionné, boolean hasFocus, int row, int column)
            {
                radioButton.setSelected(Boolean.TRUE.equals(valeur));
                return radioButton;
            }
     
     
            @Override public Component getTableCellEditorComponent(JTable table, Object valeur, 
                                                     boolean estSélectionné, int row, int column)
            {
                radioButton.setSelected(Boolean.TRUE.equals(valeur));
                return radioButton;
            }
     
     
            @Override public void actionPerformed(ActionEvent e)
            {
                stopCellEditing();
            }
     
     
            @Override public Object getCellEditorValue()
            {
                return radioButton.isSelected();
            }
        }
     
    }
    2) MonModèleTable
    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
    package test_table;
     
    import java.util.List;
    import java.util.ArrayList;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    // import javax.swing.ButtonGroup;
    import javax.swing.table.AbstractTableModel;
     
     
    class MonModèleTable extends AbstractTableModel implements PropertyChangeListener
    {   
        // Contient et gère les rangées de boutons-poussoirs et leurs regroupements.
        private GestionnObjetsDUneRangée gestionn_DonnéesDUneRang;
        private final List<GestionnObjetsDUneRangée> gestionn_DonnéesTteLatable = new ArrayList<>();
     
     
        public MonModèleTable()
        {
            super();            // AbstractTableModel()
     
            MonObjet objet;
     
            for (short idxRang = 0 ; idxRang < 6 ; idxRang++)
            {   
                gestionn_DonnéesDUneRang = new GestionnObjetsDUneRangée();
     
                for (short idxColo = 0 ; idxColo < 4 ; idxColo++)
                {
                    objet = new MonObjet(idxRang, idxColo);
                    gestionn_DonnéesDUneRang.ajoutObjetÀRangée(objet);
                   /* Pour enregistrer 'MonModèleTable' comme 'listener' des messages envoyés par 
                    * chaque objet de la liste de 'gestionn_DonnéesDUneRang'.       */
                    objet.getPropertyChangeSupport().addPropertyChangeListener(this);
                }
     
               /* Pour enregistrer 'this' (= MonModèleTable) comme 'listener' des 
                * messages envoyés par l'objet ...
                * - vers lequel une propriété (gestionn_DonnéesDUneRang) de 'MonModèleTable'-même 
                * fait référence et 
                * - d'une classe (GestionnObjetsDUneRangée) possédant une propriété (suppoChangePropri)
                * référençant une instanciation de PropertyChangeSupport. Celle-ci ayant pour 
                * argument l'objet de classe 'GestionnObjetsDUneRangée' même.        */
                gestionn_DonnéesDUneRang.suppoChangePropri.addPropertyChangeListener(this);
     
                gestionn_DonnéesTteLatable.add(gestionn_DonnéesDUneRang);
            }
        }
     
     
       /* Rem.: Identité de la rangée et de la colonne de l'objet (B-P) disponible dans 
        * 'evt.getSource();'.               */ 
        @Override public void propertyChange(PropertyChangeEvent evt)
        {
            Object objet2 = evt.getSource();
            if (objet2 == gestionn_DonnéesDUneRang)
            {
                if (evt.getPropertyName().equals("objecten"))   // MonModèleTable
                {
                    ((MonObjet) evt.getNewValue()).getPropertyChangeSupport().addPropertyChangeListener(this);
                }
                fireTableDataChanged();
            } else if (objet2 instanceof MonObjet)
            {   // Lorsqu'un autre bout-pouss d'une rangée a été sélectionné ("geselecteerd")
                // ?    Lorsque  (evt.propertyName = "dataVanEenRij")
                // int colon = gestionn_DonnéesDUneRang.getObjetsDUneRangée().indexOf((MonObjet) objet2);
                // MonObjet objet3 = (MonObjet) gestionn_DonnéesDUneRang.getObjetsDUneRangée().get(colon);
                short[] coordBP = ((MonObjet) objet2).getCoordBP();
                fireTableRowsUpdated(coordBP[0], coordBP[0]);     // [0] : rangée 2 x
            }
        }
     
     
        @Override public int getColumnCount()
        {
            return gestionn_DonnéesDUneRang.getObjetsDUneRangée().size();
        }
     
     
        @Override public int getRowCount()
        {
            return gestionn_DonnéesTteLatable.size();
        }
     
     
        public MonObjet getValueAt(int col)
        {
            return gestionn_DonnéesDUneRang.getObjetsDUneRangée().get(col);
        }
     
     
        // Implements method from javax.swing.table.TableModel
        @Override public Object getValueAt(int idxRang, int idxColo)
        {   
            return getValueAt(idxColo).isSélectionné();
        }
     
     
        // Cette méthode amène entre autre aussi idxRang2 et idxColo2 dans cette classe. 
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public void setValueAt(Object bpActionné, int idxRang2, int idxColo2)
        {
            getValueAt(idxColo2).setSélectionné(Boolean.TRUE.equals(bpActionné));
        }
     
     
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public boolean isCellEditable(int idxRang3, int idxColo3)
        {
            return true;
        }
     
     
        /** There must be a specification of a renderer for the cells for the table not to invoke the 
         * table model's 'getColumnClass' method (which gets the data type of the column's cells).     */
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public Class<?> getColumnClass(int rang)
        {
            return Object.class;
        }
     
     
        Class<?> getClasseDeCellule(int idxRang, int idxColo)
        {   
    // À modifier
            return Object.class;
        }
     
     
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public String getColumnName(int colo)
        {   // Libellé des colonnes
            return "Col " + (colo + 1);
        }
     
    }
    3) GestionnObjetsDUneRangé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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    package test_table;
     
    import java.beans.PropertyChangeSupport;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.ButtonGroup;
     
     
    class GestionnObjetsDUneRangée
    {   
        private final List<MonObjet> objetsDUneRangée = new ArrayList<>();
    //    private final ButtonGroup groupeHorizBoutRad = new ButtonGroup();
        PropertyChangeSupport suppoChangePropri = new PropertyChangeSupport(this);
     
     
        // GestionnObjetsDUneRangée()    {   }
     
     
        public void ajoutObjetÀRangée(MonObjet objet)
        {
            objetsDUneRangée.add(objet);
            setGestionn_ObjetsDUneRangée2(objet);
            suppoChangePropri.firePropertyChange("objecten", null, objet);
        }
     
     
        public List<MonObjet> getObjetsDUneRangée()
        {
            return objetsDUneRangée;
        }
     
     
        // Met tous les boutons-poussoirs d'une rangée dans leurs états adéquats. 
        public void miseàjourTousBP_Rangée(MonObjet myObject)
        {
            for (MonObjet obj : objetsDUneRangée)
            {
                obj.setSélectionné(myObject == obj);
            }
        }
     
     
        // - Méthode appelée explicitement par 'ajoutObjetÀRangée(...)' dans 'GestionnObjetsDUneRangée'.
        void setGestionn_ObjetsDUneRangée2(MonObjet monObjet)
        {
            monObjet.gestionn_ObjetsDUneRangée = this;
            monObjet.supportChangtPropri.firePropertyChange("dataVanEenRij", null,
                                                              monObjet.gestionn_ObjetsDUneRangée);
        }
     
     
        GestionnObjetsDUneRangée getGestionn_ObjetsDUneRangée2(MonObjet monObjet)
        {
            return monObjet.gestionn_ObjetsDUneRangée;
        }
    }
    4) Mon Objet
    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
    package test_table;
     
    import java.beans.PropertyChangeSupport;
     
     
    /**
     * Bean
     */
    class MonObjet
    {   
        private boolean sélectionné;
        GestionnObjetsDUneRangée gestionn_ObjetsDUneRangée;
        final PropertyChangeSupport supportChangtPropri;
        short[] coordBP = new short[2];     // idxRang et idxColo de l'objet à Bouton-Poussoir
     
     
        MonObjet(short idxRang, short idxColo)
        {
            supportChangtPropri = new PropertyChangeSupport(this);
            coordBP[0] = idxRang;
            coordBP[1] = idxColo;
        }
     
     
        PropertyChangeSupport getPropertyChangeSupport()
        {
            return supportChangtPropri;
        }
     
     
        boolean isSélectionné()
        {
            return sélectionné;
        }
     
     
        // Appelée par positionnerSélectionné(objet) dans 'gestionn_DObjetsDUneRang').
        void setSélectionné(boolean sélectionné2)
        {
            if (this.sélectionné != sélectionné2)
            {   // Ne passe ici que s'il y a changement d'état.
                this.sélectionné = sélectionné2;
                if (sélectionné)
                {   // Ne passe ici que si le b-p vient d'être actionné.
                    // 'sélectionné' de l'objet est déjà 'true'.
                    gestionn_ObjetsDUneRangée.miseàjourTousBP_Rangée(this);
                }
                supportChangtPropri.firePropertyChange("geselecteerd", !sélectionné, sélectionné);
            }
        }
     
        short[] getCoordBP()
        {
            return coordBP;
        }
    }
    Problème : Des boutons-poussoirs des rangées inférieures changent d'état aussi.
    Raison : Dans 'MonModèleTable', dans 'void propertyChange(PropertyChangeEvent evt)', le 'gestionn_ObjetsDUneRangée' de 'objet2' est toujours celui de la dernière rangée.
    Comment obtenir le bon 'gestionn_ObjetsDUneRangée', c à d qui correspond à la rangée du bouton-radio qui vient d'être actionné ?

    Merci d'avance, les as.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut
    Ah ? Aucune réponse ... Parce qu'une table dont quelques colonnes contigües contiennent de JRadioBoutons ne s'avère pas d'intérêt assez général ? Je ne pense pas que ce soit parce que le code d'une telle table est trop complexe pour les grosses têtes de Développez.net.
    Entretemps, j'ai trouvé la réponse. Je vous l'expose ici sous forme de CCSSE en quatre fichiers, pensant que certains programmeurs aimeraient recevoir cette fonctionnalité. Vous trouverez suffisamment d'explication (je crois) en commentaire dans le code. Dites-moi si je me trompe quant à l'utilité de cette fonctionnalité, les faiblesses de mon code, etc.

    Table_NRangées_BoutRadio :
    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
    /* But : 
     * Un tableau de p. ex. 4 colonnes de cases contenant chacune un bouton-radio.
     * Plusieurs rangées et une ArrayList<MyObjectManager> 
     * Les boutons-radios sont regroupée et inter-agissent par rangée entière de la table.
     * Pas d'autre type d'élément dans chaque rangée et pas de rangée contenant un autre type 
     * d'élément.
     * 
     * @author Chavadam
     */
    package table_nrangées_boutradio;
     
    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    import javax.swing.AbstractCellEditor;
    import javax.swing.JFrame;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;     // main()
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
     
     
    public class Table_NRangées_BoutRadio
    {
        private JFrame cadre;
        private JTable table;
     
     
        protected void initUI()
        {
            table = new JTable(new MonModèleTable());
            short nbreColo = (short) table.getColumnCount();
            table.setRowHeight(25);
            TableColumn col;
     
            // With Java, you can specify cell renderers and editors either by column or by data type.
            for (int i = 0 ; i < nbreColo ; i++)
            {
                col = table.getColumnModel().getColumn(i);
                col.setMaxWidth(50);
                col.setCellEditor  (new RendeurEditeur_CelluleBoutonRadio());
                col.setCellRenderer(new RendeurEditeur_CelluleBoutonRadio());
            }
     
            cadre = new JFrame();
            cadre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            cadre.add(new JScrollPane(table), BorderLayout.CENTER);
            cadre.pack();
            cadre.setVisible(true);
        }
     
     
        /**
         * @param args the command line arguments
         * @throws ClassNotFoundException
         * @throws InstantiationException
         * @throws IllegalAccessException
         * @throws UnsupportedLookAndFeelException
         */
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, 
                                                IllegalAccessException, UnsupportedLookAndFeelException
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override public void run()     // Implements method from java.lang.Runnable
                {
                    new Table_NRangées_BoutRadio().initUI();
                }
            }                         );
        }
     
     
     
        private class RendeurEditeur_CelluleBoutonRadio extends AbstractCellEditor
                implements TableCellRenderer, TableCellEditor, ActionListener
        {
            private final JRadioButton boutonRadio;
     
     
            public RendeurEditeur_CelluleBoutonRadio()
            {
                this.boutonRadio = new JRadioButton();
                boutonRadio.addActionListener(this); 
                boutonRadio.setOpaque(false);
            }
     
     
            @Override public Component getTableCellRendererComponent(JTable table, Object valeur, 
                                    boolean estSélectionné, boolean aLeFocus, int rangée, int colonne)
            {
                boutonRadio.setSelected(Boolean.TRUE.equals(valeur));
                return boutonRadio;
            }
     
     
            @Override public Component getTableCellEditorComponent(JTable table, Object valeur, 
                                                     boolean estSélectionné, int rangée, int colonne)
            {
                boutonRadio.setSelected(Boolean.TRUE.equals(valeur));
                return boutonRadio;
            }
     
     
            @Override public void actionPerformed(ActionEvent e)
            {
                stopCellEditing();
            }
     
     
            @Override public Object getCellEditorValue()
            {
                return boutonRadio.isSelected();
            }
        }
     
    }
    MonModèleTable :
    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
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    package table_nrangées_boutradio;
     
    import java.util.List;
    import java.util.ArrayList;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    // import javax.swing.ButtonGroup;
    import javax.swing.table.AbstractTableModel;
     
     
    /**
     */
    class MonModèleTable extends AbstractTableModel implements PropertyChangeListener
    {   
        // Contient et gère les rangées de boutons-radios et leurs regroupements.
        private GestionnObjetsDUneRangée gestionnObjetsDUneRangée;
        private final List<GestionnObjetsDUneRangée> gestionnDonnéesTteLatable = new ArrayList<>();
        private int colCommencementBoutRadio = 0;
        private int colFinBoutRadio = 0;
     
     
        public MonModèleTable()
        {
            super();            // AbstractTableModel()
     
            for (short idxRang = 0 ; idxRang < 5 ; idxRang++)
            {   
                gestionnObjetsDUneRangée = new GestionnObjetsDUneRangée();
     
               /* Pour que le support de changement de propriété 'suppChanProp_GestRang' propre 
                * à ce 'gestionnObjetsDUneRangée' enregistre 'monModèleTable' comme guêteur 
                * de changement de chacune des propriétés de ce gestionnObjetsDUneRangée. 
                */
                // gestionnObjetsDUneRangée.getSuppoChangePropri().addPropertyChangeListener(this);
                gestionnObjetsDUneRangée.ajoutGuêteurChangePropri(this);
     
                for (short idxColo = 0 ; idxColo < 4 ; idxColo++)
                {
                    MonObjet objet = new MonObjet(idxRang, idxColo);
     
                   /* Pour que le support de changement de propriété 'suppChanProp_Obj' 
                    * propre à ce nouvel objet enregistre 'monModèleTable' comme guêteur 
                    * de changement de chacune des propriétés de ce nouvel objet. */
                    objet.ajoutGuêteurChangtPropr(this);
     
                   /* Grâce à 'setGestionnObjetsDUneRangée(...)' dans 'ajoutObjetÀRangée(...)' 
                    * dans 'GestionnObjetsDUneRangée', la propriété 'gestionnObjetsDUneRangée2' 
                    * dans 'objet' réfèrera au 'gestionnObjetsDUneRangée' d'ici ('monModèleTable') */
                    gestionnObjetsDUneRangée.ajoutObjetÀRangée(objet);
     
                    if (idxColo == 0)
                        objet.setSélectionné(true);
                }
     
                gestionnDonnéesTteLatable.add(gestionnObjetsDUneRangée);
            }
     
            colFinBoutRadio = getColumnCount();
        }
     
     
       /** Rem.: Identité de la rangée et de la colonne de l'objet (B-P) disponible dans 
        * 'evt.getSource();'.               
        * Overrides the sole method from interface PropertyChangeListener.
        */ 
        @Override public void propertyChange(PropertyChangeEvent evt)
        {
            Object objet2 = evt.getSource();
     
            if (objet2 == gestionnObjetsDUneRangée)
    //        if (objet2 instanceof GestionnObjetsDUneRangée)
            {
                if (evt.getPropertyName().equals("objectBijgevoegd"))   // MonModèleTable
                {   // Constructeur
                } else 
                if (evt.getPropertyName().equals("objectenVanEenRij"))   
                {   // Ne passe jamais par ici.
                } else 
                if (evt.getPropertyName().equals("dataVanEenRij"))
                {   // Ne passe jamais par ici.
                }
                ;
                fireTableDataChanged();
            } else
            if (objet2 instanceof MonObjet)
            {
                if (evt.getPropertyName().equals("juistVeranderd"))     // "selected"
                {   // Constructeur et utilisation
                } else 
                if (evt.getPropertyName().equals("ManagerObjectenVanEenRij"))
                {   // Constructeur
                }
                ;
                // Lorsqu'un autre bouton-radio d'une rangée a été sélectionné ("juistVeranderd")
                short[] coordBP = ((MonObjet) objet2).getCoordBP();
                fireTableRowsUpdated(coordBP[0], coordBP[0]);     // [0] : Rien que la rangée concernée.
            }
        }
     
     
        // Implements method from javax.swing.table.TableModel
        @Override public int getColumnCount()
        {
            return gestionnObjetsDUneRangée.getObjetsDUneRangée().size();
        }
     
     
        // Implements method from javax.swing.table.TableModel
        @Override public int getRowCount()
        {
            return gestionnDonnéesTteLatable.size();
        }
     
     
        // Boolean ou String ou Checkbox
        @Override public Object getValueAt(int rang, int colo)
        {   
            if (colo < colCommencementBoutRadio)
            {
                // Plus tard
            } else
            if (colo >= colCommencementBoutRadio && colo <= colFinBoutRadio-1)
            {   // Bouton radio : Boolean
                return getValeurÀ(rang, colo).isSélectionné();
            } else
            if (colo > colFinBoutRadio-1)
            {
                // Plus tard
            }
            ;
            return null;    // Ne passe jamais ici.
        }
     
     
        MonObjet getValeurÀ(int rang, int colo)
        {
            return gestionnDonnéesTteLatable.get(rang).getObjetsDUneRangée().get(colo);
        }
     
     
       /** N'a pour but d'activer ou de désactiver le bouton-radio que d'une seule cellule 
       ¨* de la table. Si c'est l'activer, les conséquences pour les autres cellules de la rangée
        * sont gérées par la méthode 'miseàjourTousBP_Rangée()' dans 'gestionnObjetsDUneRangée', 
        * elle-même appelée ici par 'setSélectionné()' dans 'monObjet'.
        * Overrides method from javax.swing.table.AbstractTableModel
        */
        @Override public void setValueAt(Object bpActionné, int idxRang2, int idxColo2)
        {
            if (idxColo2 >= colCommencementBoutRadio && idxColo2 <= colFinBoutRadio-1)
            {
                ((MonObjet) getValeurÀ(idxRang2, idxColo2)).setSélectionné(Boolean.TRUE.equals(bpActionné));
            }
        }
     
     
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public boolean isCellEditable(int idxRang3, int idxColo3)
        {
            return true;       // idxRang3 == 1;
        }
     
     
        /** There must be a specification of a renderer for the cells, for the table not to invoke the 
         * table model's 'getColumnClass' method (which gets the data type of the column's cells).     */
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public Class<?> getColumnClass(int rang)
        {
            return Object.class;
        }
     
     
        Class<?> getClasseDeCellule(int idxRang, int idxColo)
        {   
    // Encore à modifier
            return Object.class;
        }
     
     
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public String getColumnName(int colo)
        {   // Libellé des colonnes
            return "Col " + (colo + 1);
        }
     
    }
    GestionnObjetsDUneRangé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
    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
    package table_nrangées_boutradio;
     
    import java.beans.PropertyChangeSupport;
    import java.beans.PropertyChangeListener;
    import java.util.ArrayList;
    import java.util.List;
    // import javax.swing.ButtonGroup;
     
     
    /** Bean. 
     * A bound property notifies listeners when its value changes. This has two implications:
     * 1. The bean class includes addPropertyChangeListener() [and removePropertyChangeListener()] 
     * methods for managing the bean's listeners. ? 'MonModèleTable' contient cette méthode !
     * 2. When a bound property is changed (dans 'Gestionn_DObjetsDUneRang gestionn_DonnéesDUneRang' et 
     * dans chaque 'MonObjet objet' créé dans 'MonModèleTable'), the bean sends a PropertyChangeEvent 
     * to its registered listeners à l'aide de 'propertyChangeSupport.firePropertyChange()'.
     * 'Gestionn_DObjetsDUneRang gestionn_DonnéesDUneRang' est instanciée dans 'MonModèleTable'.
     * 'setGestionn_ObjetsDUneRangée2(Gestionn_DObjetsDUneRang ...) est implémentée dans 'MonObjet' 
     * La seule classe guêteuse (Listener) de 'GestionnObjetsDUneRangée' est 'MonModèleTable'.
     * La seule classe guêteuse (Listener) de 'MonObjet' est 'MonModèleTable'.
     */
    class GestionnObjetsDUneRangée
    {   
        private List<MonObjet> objetsDUneRangée = new ArrayList<>();
    //    private final ButtonGroup groupeHorizBoutRad = new ButtonGroup();
        private final PropertyChangeSupport suppChanProp_GestRang = new PropertyChangeSupport(this);
     
     
        // GestionnObjetsDUneRangée()    {   }
     
     
        public List<MonObjet> getObjetsDUneRangée()
        {
            return objetsDUneRangée;
        }
     
     
        public void setObjetsDUneRangée(List<MonObjet> objetsDUneRangée2)
        {
            List<MonObjet> ancienObjetsDUneRangée = objetsDUneRangée;
            objetsDUneRangée = objetsDUneRangée2;
            suppChanProp_GestRang.firePropertyChange("objectenVanEenRij",
                                     ancienObjetsDUneRangée, objetsDUneRangée);
        }
     
     
        // Méthode appelée répétitivement par le constructeur de 'MonModèleTable'.
        public void ajoutObjetÀRangée(MonObjet objet)
        {
            objetsDUneRangée.add(objet);
            objet.setGestionnObjetsDUneRangée(this);
    /*        objet.getSupportChangtPropri().firePropertyChange("dataVanEenRij", null,
                                                              objet.getGestionn_ObjetsDUneRangée());
    */
            suppChanProp_GestRang.firePropertyChange("objectBijgevoegd", null, objet);
        }
     
     
       /* Méthode appelée explicitement et rien que par 'ajoutObjetÀRangée(...)' dans ce 
        * 'GestionnObjetsDUneRangée'.
        void setGestionnObjetsDUneRangée(MonObjet monObjet)
        {
            monObjet.gestionnObjetsDUneRangée2 = this;
            monObjet.getSupportChangtPropri().firePropertyChange("dataVanEenRij", null, 
                                                              monObjet.gestionn_ObjetsDUneRangée);
        }
        */
     
     
       /** Appelée par 'setSélectionné()' dans 'monObjet'.
        * Met tous les boutons-radios d'une rangée dans leurs états adéquats.
        */
        public void miseàjourTousBP_Rangée(MonObjet objetActionné)
        {
            for (MonObjet obj : objetsDUneRangée)
            {
                obj.setSélectionné(objetActionné == obj);
            }
        }
     
     
    /*    
        GestionnObjetsDUneRangée getGestionn_ObjetsDUneRangée(MonObjet monObjet)
        {
            return monObjet.getGestionn_ObjetsDUneRangée();
        }
    */    
     
        PropertyChangeSupport getSuppoChangePropri()
        {
            return suppChanProp_GestRang;
        }
     
     
        void ajoutGuêteurChangePropri(PropertyChangeListener listener)
        {
            suppChanProp_GestRang.addPropertyChangeListener(listener);
        }
     
     
        void retraitGuêteurChangePropri(PropertyChangeListener listener)
        {
            suppChanProp_GestRang.removePropertyChangeListener(listener);
        }
    }
    MonObjet :
    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
    package table_nrangées_boutradio;
     
    import java.beans.PropertyChangeSupport;
    import java.beans.PropertyChangeListener;
     
     
    /**
     * Bean
     */
    class MonObjet
    {   
        private boolean sélectionné;
        private GestionnObjetsDUneRangée gestionnObjetsDUneRangée2;
        private final short[] coordBP = new short[2];     // idxRang et idxColo de l'objet à Bouton-Radio
        private final PropertyChangeSupport suppChanProp_Obj;
     
     
        MonObjet(short idxRang, short idxColo)
        {
            suppChanProp_Obj = new PropertyChangeSupport(this);
            coordBP[0] = idxRang;
            coordBP[1] = idxColo;
        }
     
     
        boolean isSélectionné()
        {
            return sélectionné;
        }
     
     
       /** Appelée par
        * - le constructeur de 'MonModèleTable()'.
        * - 'setValueAt()' dans 'MonModèleTable()'.
        * - positionnerSélectionné(objet) dans 'gestionnObjetsDUneRangée').
        */
        void setSélectionné(boolean sélectionné2)
        {
            if (this.sélectionné != sélectionné2)
            {   // Ne passe par ici que s'il y a changement d'état.
                this.sélectionné = sélectionné2;
                if (sélectionné == true)
                {   // Ne passe par ici que si le b-p vient de passer à 'true'.
                   /* 'gestionnObjetsDUneRangée2' est devenu une référence concrète (non nulle) dans 
                    * le constructeur de 'MonModèleTable()' par l'appel de 'gestionnObjetsDUneRangée.
                    * ajoutObjetÀRangée()' qui contient l'appel de 'objet.setGestionnObjetsDUneRangée()'.
                    */
                    gestionnObjetsDUneRangée2.miseàjourTousBP_Rangée(this);
                }
                suppChanProp_Obj.firePropertyChange("juistVeranderd", !sélectionné, sélectionné);
            }
        }
     
     
        // Méthode appelée par 'ajoutObjetÀRangée(MonObjet objet)' dans 'GestionnObjetsDUneRangée'.
        void setGestionnObjetsDUneRangée(GestionnObjetsDUneRangée gestionnObjetsDUneRangée3)
        {
            GestionnObjetsDUneRangée ancienGestionnObjetsDUneRangée = gestionnObjetsDUneRangée2;
     
           /* Une référence (gestionnObjetsDUneRangée2) au conteneur de l'objet (gestionnObjetsDUneRangée) 
            * placée dans chaque objet s'avère nécessaire dans/lorsque ...          */
            this.gestionnObjetsDUneRangée2 = gestionnObjetsDUneRangée3;
     
            suppChanProp_Obj.firePropertyChange("ManagerObjectenVanEenRij",
                                    ancienGestionnObjetsDUneRangée, gestionnObjetsDUneRangée3);
        }
     
     
        // Méthode appelée par 'ajoutObjetÀRangée(MonObjet objet)' dans 'GestionnObjetsDUneRangée'.
        GestionnObjetsDUneRangée getGestionnObjetsDUneRangée()
        {
            return gestionnObjetsDUneRangée2;
        }
     
     
        PropertyChangeSupport getSupportChangtPropri()
        {
            return suppChanProp_Obj;
        }
     
     
        short[] getCoordBP()
        {
            return coordBP;
        }
     
     
        void ajoutGuêteurChangtPropr(PropertyChangeListener listener)
        {
            suppChanProp_Obj.addPropertyChangeListener(listener);
        }
     
     
        void retraitGuêteurChangtPropr(PropertyChangeListener listener)
        {
            suppChanProp_Obj.removePropertyChangeListener(listener);
        }
    }
    Cut and Paste; chez moi, cela fonctionne sans génération d'erreur.
    Dans mon code, j'ai l'habitude de mettre dans une langue autre que l'Anglais tous les libellés propres à mon application, pour les distinguer des propriétés, méthodes, ... des librairies employées.
    Désolé de ne pas encore m'être débarrassé des lettres accentuées en Français; c'est parce que cela ne m'a pas encore occasionné d'ennui. Je programme toujours dans le même environnement.
    Je ne suis programmeur qu'occasionnellement; en guise de support à mes spécialités, de surcroît à la retraite.

    En espérant faire plaisir ...

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut
    Bonjour,
    Cette intervention ne comporte pas de question, mais offre plutôt un utile éclaircissement : La séquence des appels des méthodes du petit programme 'Table_NRangées_BoutRadio' en 4 classes présenté dans l'intervention précédente. On sait en effet que les classes de Swing font des appels de méthodes (@override ...) suite à des actionnements de boutons-radios, boutons-poussoirs, ...
    Ordre des appels de méthodes
    Le bouton-radio activé avant le nouvel actionnement est en 1e, et puis en 2e colonne de la 1e rangée.
    Le bouton-radio effectivement actionné est d'abord celui de la 2e et puis en 1e colonne.

    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
    isCellEditable(0,1)	MonModTable	true
    La colonne dont le radio-bouton vient d'être actionné.
    @ getValueAt(0,1)(0,0)	MonModTable
    	isSélectionné()	false
    @ getTableCellEditorComponent(false,0,1)(false,0,0)	RendEdit_CellBoutRad
    	boutonRadio.setSelected(false)
    		@ setValueAt(0,1)(0,0)	MonModTable
    			getValeurÀ(0,1)(0,0)
    			setSélectionné(true)	MonObjet
    				miseàjourTousBP_Rangée()	GestionnObjetsDUneRangée
    [x le nbreCol] objetActionné == obj pour l'objet de colonne 1, puis 0.
    					setSélectionné()	MonObjet
    					if false
    						break;
    					if true
    						miseàjourTousBP_Rangée()	GestionnObjetsDUneRangée
    							setSélectionné()	MonObjet	GestionnObjetsDUneRangée
    				firePropertyChange()
    actionPerformed()	Table_NRangées_BoutRadio
    	stopCellEditing()	Table_NRangées_BoutRadio
    
    @ getCellRenderer(0,0)(0,0)	Table_NRangées_BoutRadio
    @ prepareRenderer(0,0)(0,0)	Table_NRangées_BoutRadio
    	super.prepareRenderer(0,0)(0,0)	Table_NRangées_BoutRadio
    		@ getValueAt(0,0)(0,0)	MonModTable
    			isSélectionné()	false
    Le b-r qui vient d'être quitté vient d'être mis à 'false'.
    		@ getTableCellRendererComponent(false,0,0)(true,0,0)	Table_NRangées_BoutRadio
    			boutonRadio.setSelected(false)(true)	Table_NRangées_BoutRadio
    
    @ getCellRenderer(0,1)(0,1)
    @ prepareRenderer(0,1)(0,1)
    	super.prepareRenderer(0,1)(0,1)
    		@ getValueAt(0,1)(0,1)
    			isSélectionné()	true
    Le b-r qui vient d'être actionné a été mis à 'true'.
    		@ getTableCellRendererComponent(true,0,1)(false,0,1)
    			boutonRadio.setSelected(true)
    
    @ getCellRenderer(0,2)(0,2)
    @ prepareRenderer(0,2)(0,2)
    	super.prepareRenderer(0,2)(0,2)
    		@ getValueAt(0,2)(0,2)
    			isSélectionné()	false
    Le b-r qui n'a pas été concerné est resté à 'false'.
    		@ getTableCellRendererComponent(false,0,2)(0,2)
    			boutonRadio.setSelected(false)
    
    La colonne dont le radio-bouton vient d'être actionné.
    @ getCellRenderer(0,1)(0,0)
    @ prepareRenderer(0,1)(0,0)
    	super.prepareRenderer(0,1)(0,0)
    		@ getValueAt(0,1)(0,0)
    			isSélectionné()	true
    		@ getTableCellRendererComponent(true,0,1)(true,0,0)
    			boutonRadio.setSelected(true)
    Ma modeste contribution, si cela peut aider celui qui veut comprendre le détail des événements ...

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

Discussions similaires

  1. JTable, un CellRenderer différent par rangée
    Par dawadam dans le forum Composants
    Réponses: 4
    Dernier message: 19/09/2011, 00h35
  2. Réponses: 5
    Dernier message: 29/09/2004, 11h05
  3. [DB2]Requête regroupement par intervals
    Par sm dans le forum DB2
    Réponses: 8
    Dernier message: 01/09/2004, 17h19
  4. TValueListEditor : Avoir des couleurs différentes par rangée
    Par Griswold dans le forum Composants VCL
    Réponses: 2
    Dernier message: 06/08/2004, 19h41
  5. Regroupement par mois
    Par fplanglois dans le forum SQL
    Réponses: 7
    Dernier message: 29/07/2003, 16h32

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