Muthamil selvi
Muthamil selvi

Reputation: 1

Selected row is not getting deleted; instead last row is getting deleted from JTable

I'm using the AbstractTableModel, and I'm trying to remove the selected row from the JTable.

I'm able to select the specific row from the table; but when I click on delete button, the selected row becomes empty (i.e. all the data in the selected row becomes null), and the last row is getting deleted from JTable.

May be, I think, fireTableRowsDeleted() is not working. Please help me on this. I've searched all over the stackoverflow, but I couldn't find the solution for it.

Please find my code below.

// Delete button listener

btnDelRow.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        //((DynamicTableModel) model).removeRow(table.getSelectedRow());
        int modelRowIndex = table.convertRowIndexToModel(table.getSelectedRow());
        DynamicTableModel model = (DynamicTableModel)table.getModel();
        model.removeRow(modelRowIndex);

// Model Class

class DynamicTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;
    ArrayList<String> taskList;
    ArrayList<String> dateList;
    Map<Integer, Map<Integer, Object>> data =
        new HashMap<Integer, Map<Integer, Object>>();
    int rows;
    int columns;
    int rowCount=0;
    int colCount;
    public DynamicTableModel(ArrayList <String> taskList, ArrayList <String> dateList) {
        this.taskList = taskList;
        this.dateList = dateList;
        rowCount = taskList.size();
    }
    @Override
    public int getRowCount() { return data.size(); }

    public int getRows() {
        return rows;
    }
    @Override
    public int getColumnCount() { return dateList.size()+2; }

    @Override
    public boolean isCellEditable(int row, int column) { 
        if (row == 0) return false;
        else return true; 
        }

    @Override
    public Object getValueAt(int row, int column)
    {
        //  Check for row

        Integer key = new Integer(row);
        Map<Integer, Object> rows = data.get(key);

        if (rows == null) return null;

        //  Now check for column

        key = new Integer(column);
        return rows.get(key);
    }

    @Override
    public String getColumnName(int column) {
    return super.getColumnName(column);
    }
    @Override
    public void setValueAt(Object value, int row, int column)
    {
        //  Save cell data
        Integer key = new Integer(row);
        Map<Integer, Object> rows = data.get(key);
        if (rows == null)
        {
            rows = new HashMap<Integer, Object>();
            if(!data.containsKey(key))
            data.put(key, rows);
        }
        key = new Integer(column);
        rows.put(key, value);
        fireTableCellUpdated(row, column);
    }
    public void addRow(){
        setValueAt("", getRowCount(), getColumnCount());
    }
    public void removeRow(int row) {
        Integer rowKey = new Integer(row);
        data.remove(rowKey);
        fireTableRowsDeleted(rowKey, rowKey);

    }
}

Please let me know if you need any other information on the same.

Example:

Say there are 7 rows in my list, when I select 4th row and click on delete button.

Instead of 4th row getting deleted, it becomes empty, i.e all the values in the 4th row becomes null (since I removed the data from the list, data.remove(row).

However, the last row (7th row) is getting deleted, since I've put data.size() in getRowCount().

Upvotes: 0

Views: 214

Answers (1)

Muthamil selvi
Muthamil selvi

Reputation: 1

I've got the solution finally. Thanks all for your help.

Root Cause:

I've used row as the key for the HashMap. Whenever I remove the particular row from the table, I'll use hashmap.remove() function will removes the data from the particular row, but will not delete the row.

Also since I used fireTableRowsDeleted() method, my table got refreshed, and it will take the new getRowCount() {hashmap.size()} which will delete the last row from the table, as the row size got decreased by 1.

Solution:

Whenever I remove particular row from the table, I'll sort and update the rest of the rows.

i.e For example, if below is my keys and values in the map(keys are nothing but the row numbers).

1st row --1, 1

2nd row --2, 3

3rd row --3, 5

Here if I delete 2nd row, then I will remove the 2nd row from the Map, and update the 3rd row, by updating its key as 2 and values remains as 5.

So the result will becomes like below.

1st row -- 1, 1

2nd row -- 2, 5

By this way I'm able to achieve the result. For this I've used concurrentskiplistmap instead of hashmap.

Please find the updated code below.

Initialization of concurrentskiplistmap

Map<Integer, Map<Integer, Object>> data = new ConcurrentSkipListMap<Integer, Map<Integer, Object>>();

RemoveRow Method:

public void removeRow(int row) {
                Integer rowKey = new Integer(row);
                data.remove(rowKey);
                sortTable(rowKey);
                fireTableRowsDeleted(rowKey, rowKey);
            }

sortTable Method:

private void sortTable(int rowkey) {
                Iterator it = data.entrySet().iterator();
                int i=0;
                while (it.hasNext()) {
                    Map.Entry pair = (Map.Entry)it.next();
                    if(i>rowkey-1){

                        Object obj = data.remove(pair.getKey());
                        data.put(i, (Map<Integer, Object>) obj);
                    }
                    i++;
                }
            }

Upvotes: 0

Related Questions