2

I have a table model containing elements of type JCheckBox. I want the content of this table to be different according to the value of a JComboBox.

My problem is the following : if I toggle a few checkboxes and then change the value of my combo box, all the check boxes take the default value (this is what I want, because the boolean values are those of the selected item in the JCheckBox) except the last one I toggled before changing the value of the combo box.

And here is how I implemented this :

public class ValsSelectionTableModel extends MyAbstractTableModel {

    private final JComboBox<Data> dataField;
    private final Map<Data, JCheckBox[][]> modifiedVals = new HashMap<>();

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Data data = (Data) dataField.getSelectedItem();
        if (!modifiedVals.containsKey(data))
            modifiedVals.put(data,
                buildCheckBoxesFrom(ClassWithStaticFields.defaultBoolArray));
        return modifiedVals.get(data)[rowIndex][columnIndex];
    }

    private JCheckBox[][] buildCheckBoxesFrom(boolean[][] boolArray) {
        JCheckBox[][] checkBoxArray = 
            new JCheckBox[boolArray.length][boolArray[0].length];
        for (int i = 0 ; i < checkBoxArray.length ; i++)
            for (int j = 0 ; j < checkBoxArray[i].length ; j++) {
                checkBoxArray[i][j] = new JCheckBox();
                checkBoxArray[i][j].setSelected(boolArray[i][j]);
                checkBoxArray[i][j].setHorizontalAlignment(SwingConstants.CENTER);
            }
        return checkBoxArray;
    }
}

Has anyone got an idea what's wrong with this ?

EDIT : I forgot something important (otherwise the JComboBox selection would not change the display) : I added this actionListener to my JComboBox :

public class MyListener implements ActionListener {

    private final ValsSelectionTableModel tableModel;

    public MyListener(ValsSelectionTableModel tableModel) {
        this.tableModel = tableModel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        tableModel.fireTableDataChanged();
    }
}
Paco
  • 43
  • 9
  • 2
    Manage elements of type `Boolean` in your `TableModel` to get the default [editor/renderer](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender). – trashgod Jul 20 '15 at 11:36
  • @trashgod Actually I already tried with Boolean, but the rendered checkboxes cannot be toggled. Do I have to set the default editor of the table for Boolean ? – Paco Jul 20 '15 at 12:13

1 Answers1

1

Manage elements of type Boolean in your TableMode to get the default renderer and editor.

I already tried with Boolean, but the rendered checkboxes cannot be toggled.

Your implementation of TableMode appears to extend AbstractTableModel; ensure that the following things happen for the relevant column:

  • Return Boolean.class from getColumnClass().

  • Return true from isCellEditable().

  • Fire the appropriate TableModelEvent in setValueAt() when updating your internal Map<…>.

Complete examples using AbstractTableModel are seen here and here. An example of adding multiple components to a column is examined here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Works perfectly well, I was missing `setValueAt()`, which I didn't know existed since I did not have to use it for my other tables. Thanks a lot ! However I still can't see what was happening in my original code (with JCheckBox). – Paco Jul 21 '15 at 09:39
  • @Paco: Glad you got it working; if `getColumnClass()` returns `Boolean.class`, you'll get a `JCheckBox` as the renderer by default. – trashgod Jul 21 '15 at 09:57