【问题标题】:How to add JRadioButton to two columuns of a JTable and ButtonGroup them.如何将 JRadioButton 添加到 JTable 和 ButtonGroup 的两个列中。
【发布时间】:2012-12-10 18:37:54
【问题描述】:

我想要一个JTable,它包含 2 列(具有 RadioButton)Active 和 Inactive 以便如果 Active Column 是 Selected 然后 Inactive RadioButton 得到 Unselected 反之亦然意味着在单行中只有 1可以从 2 个单选按钮中选择单选按钮。单选按钮的代码如下。我无法为这 2 列添加 2 个按钮组。

 public class NewJFrame extends javax.swing.JFrame {
    DefaultTableModel dt;
    public JRadioButton radioButton=new JRadioButton();


       public class RadioButtonCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener {



            public RadioButtonCellEditorRenderer() {

                radioButton.addActionListener(this);
                radioButton.setOpaque(false);
            }

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                radioButton.setSelected(Boolean.TRUE.equals(value));
                return radioButton;
            }

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                radioButton.setSelected(Boolean.TRUE.equals(value));
                return radioButton;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                stopCellEditing();
            }

            @Override
            public Object getCellEditorValue() {
                return radioButton.isSelected();
            }

        }

        public NewJFrame() {
            initComponents();

            for(int i=0;i <10;i++)
            {


                  //ButtonGroup bp[i]= new ButtonGroup();
            dt.addRow(new Object[]{null,false,false});


            }
           // jTable1.setValueAt(false, 5, 1);

        }

        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {

            buttonGroup1 = new javax.swing.ButtonGroup();
            jScrollPane4 = new javax.swing.JScrollPane();
            jTable1 = new javax.swing.JTable();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            dt= (new javax.swing.table.DefaultTableModel(new Object[][]{{null,null,null}},new String [] {"Name","Select", "Unselect"})
                {
                    Class[] types = new Class [] {java.lang.Integer.class,java.lang.String.class, java.lang.String.class};

                    public Class getColumnClass(int columnIndex) {
                        return types [columnIndex];
                    }
                    public boolean isCellEditable(int r,int c)
                    {

                        return true;
                    }
                });

                //JTextField textBox= new JTextField();
                jTable1.setModel(dt);
                TableColumn column = jTable1.getColumnModel().getColumn(1);
                column.setCellEditor(new RadioButtonCellEditorRenderer());
                column.setCellRenderer(new RadioButtonCellEditorRenderer());
                TableColumn column1 = jTable1.getColumnModel().getColumn(2);
                column1.setCellEditor(new RadioButtonCellEditorRenderer());
                column1.setCellRenderer(new RadioButtonCellEditorRenderer());
                jTable1.getTableHeader().setReorderingAllowed(false);
                jScrollPane4.setViewportView(jTable1);

                javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
                getContentPane().setLayout(layout);
                layout.setHorizontalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(13, Short.MAX_VALUE))
                );
                layout.setVerticalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(28, 28, 28)
                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(29, Short.MAX_VALUE))
                );

                pack();
            }// </editor-fold>

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            /* Set the Nimbus look and feel */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
             * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new NewJFrame().setVisible(true);
                }
            });
        }

【问题讨论】:

    标签: java swing jtable jradiobutton buttongroup


    【解决方案1】:

    这是我拥有的示例代码,我对其进行了修改,并根据您的要求在第 2 列中放置了另一个 JRadioButton。第一列和第二列都像 ButtonGroup 一样按行分组。

    输出:

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.DefaultCellEditor;
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JDialog;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableCellRenderer;
    
     /** Dialog class **/
    public class DisplayTable extends JDialog {
       public void initialize() {
    
       SourceTableModel stm = new SourceTableModel();
       JTable sourceTable = new JTable(stm);
    
       sourceTable.getColumnModel().getColumn(0).setCellRenderer(new RadioButtonRenderer());
       sourceTable.getColumnModel().getColumn(0).setCellEditor(new RadioButtonEditor(new JCheckBox()));
    
    sourceTable.getColumnModel().getColumn(1).setCellRenderer(new RadioButtonRenderer());
    sourceTable.getColumnModel().getColumn(1).setCellEditor(new RadioButtonEditor(new JCheckBox()));
    
    JPanel panel = new JPanel();
    panel.add(new JScrollPane(sourceTable));
    add(panel, BorderLayout.CENTER);
    
    JPanel btnPanel = new JPanel();
    JButton btnApply = new JButton("Close");
    btnPanel.add(btnApply);
    
    btnApply.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.exit(0);
        }
    });
    
    add(btnPanel, BorderLayout.SOUTH);
    
    setTitle("Radio Button in JTable Example");
    setModal(true);
    pack();
    setVisible(true);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DisplayTable().initialize();
            }
        });
    }
    
    }
    
    /** Table Model class for the Table **/
    class SourceTableModel extends AbstractTableModel  {
    
    private static final long serialVersionUID = 1L;
    
    private List<SourceModel> sourceList = new ArrayList<SourceModel>(); 
    private String[] columnNamesList = {"Active", "InActive", "One", "Two"};
    
    public SourceTableModel() {
        this.sourceList = getSourceDOList();
    }
    
    @Override
    public String getColumnName(int column) {
        return columnNamesList[column];
    }
    
    @Override
    public int getRowCount() {
        return sourceList.size();
    }
    
    @Override
    public int getColumnCount() {
        return columnNamesList.length;
    }
    
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return ((columnIndex == 0 || columnIndex == 1) ? Boolean.class : String.class);
    }
    
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return ((columnIndex == 0 || columnIndex == 1) ? true : false);
    }
    
    /**
         **Important:** Here when ever user clicks on the column one then other column values should be made false. Similarly vice-versa is also true.
    **/
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        SourceModel model = (SourceModel) sourceList.get(rowIndex);
        switch (columnIndex) {
    case 0: 
            model.setSelect(true);
            model.setInActive(false);
            fireTableRowsUpdated(0, getRowCount() - 1);
            break;
    case 1:
            model.setSelect(false);
            model.setInActive(true);
            fireTableRowsUpdated(0, getRowCount() - 1);
            break;
    case 2: 
        model.setFactory((String) aValue);
        break;
    case 3: 
        model.setSupplier((String) aValue);
        break;
    }
    fireTableCellUpdated(rowIndex, columnIndex);
    }
    
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
    SourceModel source = sourceList.get(rowIndex);
    //SourceModel source = getSourceDOList().get(rowIndex);
    switch(columnIndex){
    case 0:
        return source.isSelect();
    case 1:
        return source.isInActive();    
    case 2:
        return source.getFactory();
    case 3:
        return source.getSupplier();
    default:
        return null;
    }
    }
    
    /**
     * List for populating the table.
     * @return list of sourceDO's.
     */
    private List<SourceModel> getSourceDOList() {
       List<SourceModel> tempSourceList = new ArrayList<SourceModel>();
       for (int index = 0; index < 5; index++) {
    
        SourceModel source = new SourceModel();
        source.setSelect(false);
        source.setInActive(false);
        source.setFactory("One " + index);
        source.setSupplier("Two " + index);
    
        tempSourceList.add(source);
    }
    return tempSourceList;
    }
    }
    
    /** Class that is holding the model for each row **/
    class SourceModel {
    
    private boolean active;
    private boolean inActive;
    private String factory;
    private String supplier;
    
    public SourceModel() {
        // No Code;
    }
    
    public SourceModel(boolean select, boolean inActive, String factory, String supplier) {
        super();
        this.active = select;
        this.inActive = inActive;
        this.factory = factory;
        this.supplier = supplier;
    }
    
    public boolean isSelect() {
        return active;
    }
    
    public void setSelect(boolean select) {
        this.active = select;
    }
    
    public String getFactory() {
        return factory;
    }
    
    public boolean isInActive() {
        return inActive;
    }
    
    public void setInActive(boolean inActive) {
        this.inActive = inActive;
    }
    
    public void setFactory(String factory) {
        this.factory = factory;
    }
    
    public String getSupplier() {
        return supplier;
    }
    
    public void setSupplier(String supplier) {
        this.supplier = supplier;
    }
    }
    
    /** Renderer class for JRadioButton **/
    class RadioButtonRenderer implements TableCellRenderer {
    
        public JRadioButton btn = new JRadioButton();
        public Component getTableCellRendererComponent(JTable table, Object value,
          boolean isSelected, boolean hasFocus, int row, int column) {
    
          if (value == null) 
              return null;
          btn.setSelected((Boolean) value);
          return btn;
      }
    }
    
    /** Editor class for JRadioButton **/
    class RadioButtonEditor extends DefaultCellEditor implements ItemListener {
    
    public JRadioButton btn = new JRadioButton();
    
    public RadioButtonEditor(JCheckBox checkBox) {
        super(checkBox);
    }
    
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
        if (value == null) 
            return null;
    
        btn.addItemListener(this);
    
        if (((Boolean) value).booleanValue())
            btn.setSelected(true);
        else
            btn.setSelected(false);
    
        return btn;
    }
    
    public Object getCellEditorValue() {
        if(btn.isSelected() == true)
            return new Boolean(true);
        else 
            return new Boolean(false);
    }
    
    public void itemStateChanged(ItemEvent e) {
        super.fireEditingStopped();
    }
    }
    

    编辑: 在表模型中定义列后,您需要使用以下语句将Rendering and Editing 用于列 0 和 1。

    sourceTable.getColumnModel().getColumn(1).setCellRenderer(new RadioButtonRenderer());
    sourceTable.getColumnModel().getColumn(1).setCellEditor(new RadioButtonEditor(new JCheckBox()));
    

    同样,您也需要为第 2 列和第 3 列(根据需要)执行此操作。您必须查看的一个重要步骤是 TableModel 中的 setValueAt(..) 方法,您需要对列 (0, 1) 和 (2, 3) 进行分组,因此当第 0 列为 selected 时,将第 1 列设为 deselected 和2 列和 3 列也是如此。查看下面案例 2 的 setValueAt(..) 方法代码。当用户选择第二列时,我们将该列设为真,第三列设为假。您只需对第 2 列和第 3 列执行相同操作即可。

       case 2:
            model.setSelect(true);
            model.setInActive(false);
            break;
    

    【讨论】:

    • +1 表示sscce,现在引用here。建议:1)使用@Override注解。 2)在可用时使用静态工厂,例如getCellEditorValue() 可以return Boolean.valueOf(btn.isSelected())。 3)在构造函数中调用addItemListener()一次,并简化逻辑,例如btn.setSelected(((Boolean) value).booleanValue()) 4) 在setValueAt() 中省略多余的种姓。
    • 感谢先生提供此代码;如果你能帮我一个忙,让 jjtable 的第 3 列和第 4 列中有两个单选按钮
    • @trashgod 谢谢。当然,我会采纳你的建议并从现在开始尝试实践它们。
    • @user1760166 这很简单。您只需要对 3 列和 4 列使用渲染器,然后像我对 1 列和 2 列所做的那样。等等,我会解释你的实现。看看我的编辑。试试看,你可以做得更好。
    猜你喜欢
    • 2012-06-30
    • 2012-06-25
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多