Delete row from JTable with custom table model

I've a subclass of JTable that uses a custom table model (an implementation of AbstractTableModel) to manage data.

The problem occurs when I try to delete a row with the method deleteRow. The row in my table is replaced by a blank string but the row is not deleted.

Here is the code:

public class LiveSearchTableModel extends AbstractTableModel 
{

  private List<String> columnNames = new ArrayList<String>();
  private Map<Point, Object> displayData = new HashMap<Point, Object>();
  private Map<Point, Object> originalData = new HashMap<Point, Object>();

  public LiveSearchTableModel(List<String> columnNames, 
      Map<Point, Object> tableData) 
  {
    this.columnNames = columnNames;
    this.displayData = tableData;
    this.originalData.putAll(tableData); 
  }

  @Override
  public int getColumnCount() {
    return columnNames.size();
  }

  @Override
  public int getRowCount() {
    return displayData.size() / columnNames.size();
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    return displayData.get(new Point(rowIndex, columnIndex));
  }

  public void deleteRow (int row)
  {
    for (int cont = 0; cont < columnNames.size();cont++)
    {   
      displayData.remove(new Point (row,cont)); 
    }

    this.fireTableRowsDeleted(row, row);
  }

  @Override
  public void setValueAt(Object value, int rowIndex, int columnIndex) 
  {
    this.displayData.put(new Point(rowIndex, columnIndex), value);
    this.fireTableDataChanged();
  }
}

Answers


The sscce below illustrates one potential problem: The keys of a Map are not ordered, while the rows of a table are. In the approach shown, an array of keys must by updated with each change to the data. See also this related example. If required, you could extend Point to implement Comparable, as shown here for Value.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

/**
* @see http://stackoverflow.com/q/12330167/230513
*/
public class TableModelTest extends JPanel {

    public TableModelTest() {
        super(new BorderLayout());
        final MyModel model = new MyModel();
        JTable table = new JTable(model);
        this.add(new JScrollPane(table));
        this.add(new JButton(new AbstractAction("Delete") {

            @Override
            public void actionPerformed(ActionEvent e) {
                model.remove(0);
            }
        }), BorderLayout.SOUTH);
    }

    public class MyModel extends AbstractTableModel {

        private List<String> names = new ArrayList<String>();
        private Map<Point, Object> data = new HashMap<Point, Object>();
        private Point[] keys;

        public MyModel() {
            this.names = Arrays.asList("Point", "Name");
            data.put(new Point(1, 1), "One");
            data.put(new Point(2, 2), "Two");
            data.put(new Point(3, 3), "Three");
            this.keys = data.keySet().toArray(new Point[data.size()]);
        }

        public void remove(int row) {
            data.remove(keys[row]);
            keys = data.keySet().toArray(new Point[data.size()]);
            this.fireTableRowsDeleted(row, row);
        }

        @Override
        public int getColumnCount() {
            return names.size();
        }

        @Override
        public String getColumnName(int col) {
            return names.get(col);
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            if (col == 0) {
                return keys[row];
            } else {
                return data.get(keys[row]);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("TableModelTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableModelTest().display();
            }
        });
    }
}

Need Your Help

Can't connect to facebook using Android SDK 3

java android facebook

I'm trying to connect to Facebook using Android SDK 3.0 and I'm getting the authorization error such as this. Searches yielded that this is probably a problem with the generated hash which was inde...

Button Thread-Safe Calls to Windows Forms Controls C#

c# multithreading winforms button windows-forms-designer

I had read this topic about how to Make Thread-Safe Calls to Windows Forms Controls .. But I don't really understand how to apply it to a button. In my case I have:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.