JRadioButton位于JTable中,按行

时间:2016-04-14 06:18:27

标签: java swing jtable jradiobutton

这是我在StackOverflow中的第一篇文章。

我没有在JTable上找到SSCCE,其行单元格包含JRadioButton的 - 在几个(不是全部)列中,连续的列并不总是每行的相同列 - 并且其ButtonGroup与行对应。 所以我在“如何使用表格 - http://docs.oracle.com/javase/tutorial/uiswing/components/table.html”中重新审视了渲染器和编辑器的主题后,尝试详细说明了这一点。 并在研究了以下讨论之后: - 将JRadioButton(一列)添加到JTable Adding jRadioButton into jTable(Guillaume Polet) - 如何在JTable How to add JRadioButton to group in JTable

中将JRadioButton添加到组中

我利用...... - 摇摆 - TableCellEditor和TableCellRenderer - Beans.PropertyChangeSupport,PropertyChangeListener

我的Java代码有效......但行为错误且不完整。 即使正在进行的功能 - 我认为 - 对于许多Java程序员来说都是非常感兴趣的。

个人风格规则:Java,Swing,......中的所有语法单词:英语,如库中一样。所有其他项目,特别是我的应用程序:另一种语言;这里是法国人。

最后,这里是包含4个子类[RendeurEditeur_CelluleBoutonRadio],[MonModeleTable],[GestionnObjetsDUneRangee]和[MonObjet]的“One copy and paste”类文件[TestTable2]。有用。这个SSCCE要复制和粘贴420行:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
// import javax.swing.ButtonGroup;
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.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;


public class TestTable2
{
    private JFrame cadre;
    private JTable table;


    protected void initUI()
    {
        table = new JTable(new MonModeleTable());
        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.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 TestTable2().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 estSelectionne, boolean hasFocus, int row, int column)
        {
            radioButton.setSelected(Boolean.TRUE.equals(valeur));
            return radioButton;
        }


        @Override public Component getTableCellEditorComponent(JTable table, Object valeur, 
                                             boolean estSelectionne, 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();
        }
    }



    /**
     *
     */
    class MonModeleTable extends AbstractTableModel implements PropertyChangeListener
    {   
        // Manages the rows of radioButtons and their groupings.
        private GestionnObjetsDUneRangee gestionn_DonneesDUneRang;
        private final List<GestionnObjetsDUneRangee>     gestionn_DonneesTteLatable = new ArrayList<>();


        public MonModeleTable()
        {
            super();            // AbstractTableModel()

            MonObjet objet;

            for (short idxRang = 0 ; idxRang < 5 ; idxRang++)
            {   
                gestionn_DonneesDUneRang = new GestionnObjetsDUneRangee();

               /* To record 'this' (= MonModeleTable) as listener of the messages sent 
                * by the object ...
                * - to which a property (gestionn_DonneesDUneRang) of 'MonModeleTable'-itself 
                * refers to, and 
                * - pertaining to a class (GestionnObjetsDUneRangee) containing a property (suppoChangePropri)
                * refering to an instanciation of PropertyChangeSupport. This later has as argument  
                * the object of class 'GestionnObjetsDUneRangee'.        */
                // Leaking 'this' in constructor : Passing suspicious parameter in the constructor.
                gestionn_DonneesDUneRang.getSuppoChangePropri().addPropertyChangeListener(this);

                for (short idxColo = 0 ; idxColo < 4 ; idxColo++)
                {
                    objet = new MonObjet(idxRang, idxColo);
                    gestionn_DonneesDUneRang.ajoutObjetÀRangee(objet);
                    if (idxColo == 0)
                        objet.setSelectionne(true);
                   /* To record 'MonModeleTable' as listener of the messages sent by each  
                    * object of the list 'gestionn_DonneesDUneRang'.*/
                    objet.getSupportChangtPropri().addPropertyChangeListener(this);
                }

                gestionn_DonneesTteLatable.add(gestionn_DonneesDUneRang);
            }
        }


        // Rem.: Identity of the object's row and column (JRadioButton) available in 'evt.getSource();'. 
        @Override public void propertyChange(PropertyChangeEvent evt)
        {
            System.out.print(evt.getPropertyName() + "\t");
            Object objet2 = evt.getSource();

            if (objet2 == gestionn_DonneesDUneRang)
            {
                if (evt.getPropertyName().equals("objecten"))   // MonModeleTable
                {
                    ((MonObjet) evt.getNewValue()).getSupportChangtPropri().addPropertyChangeListener(this);
                }
                fireTableDataChanged();
                System.out.println("");
            } else if (objet2 instanceof MonObjet)
            {   // When another button of the row has been activated ("geselecteerd")
                short[] coordBP = ((MonObjet) objet2).getCoordBP();
                fireTableRowsUpdated(coordBP[0], coordBP[0]);     // [0] : 2 x row

                System.out.println("");
            }
        }


        @Override public int getColumnCount()
        {
            return gestionn_DonneesDUneRang.getObjetsDUneRangee().size();
        }


        @Override public int getRowCount()
        {
            return gestionn_DonneesTteLatable.size();
        }


        // Exporting non-public type through public API
        public MonObjet getValueAt(int col)
        {
            return gestionn_DonneesDUneRang.getObjetsDUneRangee().get(col);
        }


        // Implements method from javax.swing.table.TableModel
        @Override public Object getValueAt(int idxRang, int idxColo)
        {   
            return getValueAt(idxColo).isSelectionne();
        }


        // This method can also import idxRang2 and idxColo2 in this class. 
        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public void setValueAt(Object bpActionne, int idxRang2, int idxColo2)
        {
            getValueAt(idxColo2).setSelectionne(Boolean.TRUE.equals(bpActionne));
        }


        // 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)
        {   
// To be modified.
            return Object.class;
        }


        // Overrides method from javax.swing.table.AbstractTableModel
        @Override public String getColumnName(int colo)
        {   // Column titles
            return "Col " + (colo + 1);
        }

    }



    /** Bean. 
     */
    class GestionnObjetsDUneRangee
    {   
        private List<MonObjet> objetsDUneRangee = new ArrayList<>();
    //    private final ButtonGroup groupeHorizBoutRad = new ButtonGroup();
        private final PropertyChangeSupport suppoChangePropri = new     PropertyChangeSupport(this);


        // GestionnObjetsDUneRangee()    {   }


        public void ajoutObjetÀRangee(MonObjet objet)
        {
            objetsDUneRangee.add(objet);
            setGestionn_ObjetsDUneRangee2(objet);
            suppoChangePropri.firePropertyChange("objecten", null, objet);
        }


        public List<MonObjet> getObjetsDUneRangee()
        {
            return objetsDUneRangee;
        }


        // ?
        public void setObjetsDUneRangee2(List<MonObjet> objetsDUneRangee2)
        {
            List<MonObjet> ancienObjetsDUneRangee = objetsDUneRangee;
            objetsDUneRangee = objetsDUneRangee2;
            suppoChangePropri.firePropertyChange("objectenVanEenRij",
                                 ancienObjetsDUneRangee, objetsDUneRangee);
        }


        // Method called from 'ajoutObjetÀRangee(...)' in this class.
        void setGestionn_ObjetsDUneRangee2(MonObjet monObjet)
        {
            monObjet.gestionn_ObjetsDUneRangee = this;
            monObjet.getSupportChangtPropri().firePropertyChange("dataVanEenRij", null,                                 monObjet.gestionn_ObjetsDUneRangee);
        }


        // Puts all the JRadioButton's of a row in their right states (Only one selected) 
        public void miseàjourTousBP_Rangee(MonObjet myObject)    // setSelectionne()
        {
            for (MonObjet obj : objetsDUneRangee)
            {
                obj.setSelectionne(myObject == obj);
            }
        }


        GestionnObjetsDUneRangee getGestionn_ObjetsDUneRangee2(MonObjet monObjet)
        {
            return monObjet.gestionn_ObjetsDUneRangee;
        }


        PropertyChangeSupport getSuppoChangePropri()
        {
            return suppoChangePropri;
        }

    /*    
        public void
        addPropertyChangeListener(PropertyChangeListener listener)
        {
            suppoChangePropri.addPropertyChangeListener(listener);
        }


        public void
        removePropertyChangeListener(PropertyChangeListener listener)
        {
            suppoChangePropri.removePropertyChangeListener(listener);
        }
    */
    }



    /**
     * Bean
     */
    class MonObjet
    {   
        private boolean selectionne;
        GestionnObjetsDUneRangee gestionn_ObjetsDUneRangee;
        private final PropertyChangeSupport supportChangtPropri;
        short[] coordBP = new short[2];     // idxRang and idxColo of the JRadioButton object


        MonObjet(short idxRang, short idxColo)
        {
            supportChangtPropri = new PropertyChangeSupport(this);
            coordBP[0] = idxRang;
            coordBP[1] = idxColo;
        }


        PropertyChangeSupport getSupportChangtPropri()
        {
            return supportChangtPropri;
        }


        boolean isSelectionne()
        {
            return selectionne;
        }


        // Called by 'positionnerSelectionne(objet)' in 'gestionn_DObjetsDUneRang').
        void setSelectionne(boolean selectionne2)
        {
            if (this.selectionne != selectionne2)
            {   // Passes here only if a change of the state occured.
                this.selectionne = selectionne2;
                if (selectionne)
                {   // Passes here only when the radiobutton just was activated.
                    // 'selectionne' of the object is already 'true'.
                    gestionn_ObjetsDUneRangee.miseàjourTousBP_Rangee(this);
                }
                supportChangtPropri.firePropertyChange("geselecteerd", !selectionne, selectionne);
            }
        }


        short[] getCoordBP()
        {
            return coordBP;
        }


        public void setGestionn_ObjetsDUneRangee(GestionnObjetsDUneRangee gestionn_ObjetsDUneRangee2)
        {
            GestionnObjetsDUneRangee ancienGestionn_ObjetsDUneRangee = gestionn_ObjetsDUneRangee;
            gestionn_ObjetsDUneRangee = gestionn_ObjetsDUneRangee2;
            supportChangtPropri.firePropertyChange("ManagerObjectenVanEenRij",
                                ancienGestionn_ObjetsDUneRangee, gestionn_ObjetsDUneRangee2);
        }

    /*    
        public void addPropertyChangeListener(PropertyChangeListener listener)
        {
            supportChangtPropri.addPropertyChangeListener(listener);
        }


        public void removePropertyChangeListener(PropertyChangeListener     listener)
        {
            supportChangtPropri.removePropertyChangeListener(listener);
        }
    */
    }

}

}

问题:RadioButton位于其中一个刚被激活的行中,在激活的列中,也会发生变化。请运行我的代码观察。 在'MonModèleTable'中,'void propertyChange(PropertyChangeEvent evt)','objet2'的'gestionn_ObjetsDUneRangée'总是指最后一行。如何到达正确的'gestionn_ObjetsDUneRangée',我的意思是对应于刚刚激活的JRadioButton行的那个?

是否有专家同意此案件具有普遍意义,谁可以帮助我们(Guillaume Polet?)? 非常感谢提前。

注意:我正在使用JRE rev。 1.8.0_73和NetBeans IDE rev。 8.0.2。

0 个答案:

没有答案