How to add JRadioButton to two columuns of a JTable and ButtonGroup them.
Asked Answered
E

1

2

I want a JTable which consists of 2 columns(having RadioButton) Active and Inactive such that if Active Column is Selected then Inactive RadioButton gets Unselected and Vice versa means that in a single row only 1 radiobutton can be selected out of 2 radiobuttons. the code for radiobutton is below . I am not able 2 add buttongroup for this 2 columns.

 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);
                }
            });
        }
Evergreen answered 24/12, 2012 at 9:47 Comment(0)
S
8

This is a sample code which I have and I modified it and placed another JRadioButton in column 2 for your requirement. Both columns one and two are grouped row wise like ButtonGroup.

Output:

enter image description here

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();
}
}

EDIT: After defining columns in the table model you need to use Rendering and Editing for columns 0 and 1 using the following statement.

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

Similarly you need to do for 2nd and 3rd columns (as you needed) also. One important step you have to look is setValueAt(..) method in the TableModel, you need to group columns (0, 1) and (2, 3) so when ever 0th column is selected then make 1st column as deselected and same is for 2 and 3 columns. Look at the setValueAt(..) method code below for case 2. When ever user selects second column then we will make that column as true and make third column as false. You just need to do the same for column-2 and column-3.

   case 2:
        model.setSelect(true);
        model.setInActive(false);
        break;
Sunday answered 24/12, 2012 at 13:52 Comment(4)
+1 for sscce, now cited here. Suggestions: 1) Use @Override annotation. 2) Use static factories when available, e.g. getCellEditorValue() can return Boolean.valueOf(btn.isSelected()). 3) Call addItemListener() once in constructor, and simplify logic, e.g. btn.setSelected(((Boolean) value).booleanValue()) 4) Omit redundant caste in setValueAt().Templet
thanx sir for this code; if you can do me a favour such that two radiobuttons arre in column 3 and column 4 of jjtableEvergreen
@Templet Thanks. Sure I will take your suggestions and try to practice them from now on.Sunday
@Evergreen Well that's simple. You just need to use renderer for 3 and 4 columns and then like the way I have done for 1 and 2 columns. Wait I will explain you about the implementation. Look at my EDIT. Try it out you can do better that this.Sunday

© 2022 - 2024 — McMap. All rights reserved.