Created Jpanel with mutiple checkboxes and rendering to JTable cell causing issue

46 Views Asked by At

I created custom cell renderer which takes value parameter from method getTableCellRendererComponent and creates check boxes based on list of values which is List of Integer.

Issue is renderer is called multiple times when window is dragged or resized and panel is adding multiple times inside the cell of JTable, resulting in duplicate JCheckBoxes.

Renderer :

public class CheckBoxCellRenderer extends JPanel implements TableCellRenderer {
    private static final long serialVersionUID = -6142180432465856711L;
    JPanel panel = new JPanel(new FlowLayout());

    public CheckBoxCellRenderer() {
        setOpaque(true);
    }
    
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if(value!=null){
            Set<Integer> intValues = (Set<Integer>) value;  
            for(Integer intvalue : intValues){
                panel.add(new JCheckBox(intvalue.toString()));
            }
        }
    //  panel.add(this);
    //  table.setRowHeight(row, this.getPreferredSize().height);
        panel.revalidate();
        panel.repaint();
        return panel;
    }
}

cell editor:

class CheckBoxCellEditor extends AbstractCellEditor implements TableCellEditor{
    private static final long serialVersionUID = 7910769369831526953L;
    JPanel panel = new JPanel(new FlowLayout());

    @Override
    public Object getCellEditorValue() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {     
        //table.setRowHeight(25);
        //table.setCellSelectionEnabled(true);
        if(value!=null){
            Set<Integer> intValues = (Set<Integer>) value;  
            for(Integer intvalue : intValues){
                panel.add(new JCheckBox(intvalue.toString()));
            }
        }
         
        //table.setRowHeight(row, panel.getPreferredSize().height);
        return panel;
    }
}

Main panel :
(infoTable is ModelTable)

infoTable.getColumnModel().getColumn(2).setCellRenderer(new CheckBoxCellRenderer());
infoTable.getColumnModel().getColumn(2).setCellEditor(new CheckBoxCellEditor());
infoTable.addNewRows(modelList);
1

There are 1 best solutions below

0
Abra On

You need to be aware that usually only one instance of TableCellRenderer is created and it is used to render every cell in the JTable.

Every time the JTable needs to be redrawn, method getTableCellRendererComponent will be called. Obviously when you drag or resize the JTable, it needs to be redrawn.

A simple solution would be to first removeAll the JCheckBoxes from the JPanel before adding the new ones.

Note that the default layout manager for class JPanel is FlowLayout so no need to explicitly set it.

public class CheckBoxCellRenderer implements TableCellRenderer {
    private static final long serialVersionUID = -6142180432465856711L;
    JPanel panel = new JPanel();
    
    @Override
    public Component getTableCellRendererComponent(JTable table,
                                                   Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus,
                                                   int row,
                                                   int column) {
        if(value!=null){
            panel.removeAll();
            Set<Integer> intValues = (Set<Integer>) value;  
            for(Integer intvalue : intValues){
                panel.add(new JCheckBox(intvalue.toString()));
            }
        }
        return panel;
    }
}