Search code examples
javaswinguser-interfacejtablejcheckbox

Question on jtable cell editors in swing


I want to implement a component that serves as a list of options, that a user can choose to select or not.
Visually I thought that it would be best presented in a UI (if there is a better approach please tell me) as follows:
enter image description here

Anyway, I thought that this could be implemented via a JTable (single column) and using a JCheckBox as a cell editor.
I tried it but did not work.
Example of code:

public class ListRenderer extends JFrame {
    
    JCheckBox checkbox = new JCheckBox("Test");
    DefaultCellEditor dce1 = new DefaultCellEditor(checkbox);
    
    public ListRenderer(){          
        
        Object[][] data =  {   {"Test"} };
        String[] columnNames = {"Options"};
        
        DefaultTableModel model = new DefaultTableModel(data,columnNames);
        
        JTable table = new JTable(model){
            
            public TableCellEditor getCellEditor(int row, int column)            
            {               
                return dce1;                
            }
            
        };
        JScrollPane scrollPane = new JScrollPane( table );        
        getContentPane().add( scrollPane );
    }

What happens is that when the frame appears I see the "Test" in the table but it does not appear like a checkbox (as in the example image).
If I click on the cell, it turns into a checkbox (click button on the left and not right) but the text changes to show either true or false! It does not keep showing "Test"
More over the text depends on whether I keep pressing on the cell or not.
If I change the JCheckBox to a JComboBox the behavior is correct as far as I can tell.
Can anyone please tell me what am I doing wrong here?
Thanks!


Solution

  • To be rendered as a JCheckBox by default, the table's model must return Boolean.class as the type for that column. If you are using DefaultTableModel, you will have to override getColumnClass() accordingly. Here's a related example.

    Addendum: Note in the example that the editor's private instance of ValueRenderer can apply ItemEvent directly, instead of via setValueAt().

    Addendum: The example has been updated to reflect the correct model-view workflow.

    setValueAt() is called anyway. Verified it via debugging

    If you step into setValueAt(), you'll see that "This empty implementation is provided so users don't have to implement this method if their data model is not editable."