Cohen
Cohen

Reputation: 79

Adding a Row in a Jtable with AbstractTableModel

I'm trying to add a row into the Jtable that extends AbstractTableModel as the following code shows:

class AbstractTable extends AbstractTableModel
{
    String[] columNames = {"name", "cc", "age", "phone", "date", "amoun"};      
    Object[][] dataRow = {{"harry", "1234","21","23594","13/3/2","3000"} };

    @Override
    public int getColumnCount()
    {
        return columNames.length;
    }

    @Override
    public int getRowCount()
    {
        return dataRow.length;
    }

    public String getColumnName(int col)
    {
        return columNames[col];//cast from object to string.            
    }

    @Override
    public Object getValueAt(int row, int col)
    {
        return dataRow[row][col];
    }

    public void setValueAt(Object value, int row, int col)
    {
        dataRow[row][col] = value;
        fireTableCellUpdated(row, col);
    }
}

Here I implement a button that tries to add a row into the Jtable model once is pressed, but it is not working and throwing an exception:

java.lang.ClassCastException: AbstractTable cannot be cast to javax.swing.table.DefaultTableModel

public void actionPerformed(ActionEvent e)
{           
    if(e.getActionCommand().equals("add client"))
    {
        Object[] dataList = {"", "", "", "", "", ""};               

        AbstractTableModel defaut = (AbstractTableModel) table.getModel();

        ((DefaultTableModel) defaut).addRow(dataList);

        labelStatus.setText("Cliente Agregado.");
    }

How can I add a row in this code properly ?

Upvotes: 2

Views: 8554

Answers (3)

Lakshan Vithana
Lakshan Vithana

Reputation: 41

You just have to properly implement the getValueAt(int, int). Below is an example:

public class PersonTableModel extends AbstractTableModel {

    String[] columnNames  = new String[] {"Name","Age","Address", "Employeement Status"};


    List<Person> data = new ArrayList<Person>();

    public PersonTableModel() {
       //(Proper way to use a setter method to set the Person)
       data.add(new Person("Sampath", "+94765154345", "34", "male", "Galle", "Contract")); 
    }

    //Abstract method implementation
    public int getRowCount() {
       return data.size();
    }

    //Abstract method implementation
    public int getColumnCount() {
       return columnNames.length;
    }

    //Abstract method implementation
    public Object getValueAt(int row, int colum) {
      Person personObj = data.get(row);

      switch(colum){
        case 0: return personObj.getName();
        case 1: return personObj.getAge();
        case 2: return personObj.getAddress();
        case 3: return personObj.getEmpStatus();
        default : return null;
      }
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }

    public void addData(Person person){
        data.add(person);
    }
}

Upvotes: 2

Dinuka Hettiarachchi
Dinuka Hettiarachchi

Reputation: 77

In AbstractTableModel there are methods to Update the table for inserting. after you added the data into the list, you have to repaint (fireTable)the table

list.add(data);
fireTableRowsInserted(list.size() - 1, list.size() - 1);

if you wont to insert one row must give starting and ending row as the same. there are other methods for updating and deleting in AbstractTableModel even for updating single cell

For more details visit

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

How can i add a row in this code properly ?

You need to re-do your model. Currently you're hard-coding the data in fixed-sized arrays which will hamstring your ability to add data. Instead:

  • Use a List<RowType> for the nucleus of your model, not a 2-d array of object. Note that RowType is a class that you create that holds all the data held in a row.
  • Use this RowType to easily get and set items from each cell. This means changing your getValueAt and setValue at methods to accommodate your RowType objects.
  • Give your model an public void addRow(RowType rowData) method that allows you to add a new object to the list. You can't use DefaultTableModel's method since your model doesn't extend this, and so you will have to write you're own.
  • Inside this method, call the appropriate fireXxxx(...) method of the super class.

Alternatively: don't have your model extend AbstractTableModel but rather have it extend DefaultTableModel and use its methods. If you go this route, you'd not have your class hold a 2D array but rather would use the Default's own data nucleus, one that you can fill and modify via the Default's super constructors and methods. You'd also do well to create an addRow method overload, one that accepts a parameter of class RowType

For example assuming a RowData class with fields and setters and getters to match the columns, you could extend DefaultTableModel to look something like this:

public class MyTableModel extends DefaultTableModel {
    public static final String[] COLUMN_NAMES = { "name", "cc", "age", "phone", "date", "amount" };

    public MyTableModel() {
        super(COLUMN_NAMES, 0);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        if (getRowCount() > 0 && getValueAt(0, columnIndex) != null) {
            return getValueAt(0, columnIndex).getClass();
        }
        return super.getColumnClass(columnIndex);
    }


    public void addRow(RowData rowData) {
        if (rowData == null) {
            throw new IllegalArgumentException("rowData cannot be null");
        }
        Vector<Object> rowVector = new Vector<>();
        rowVector.add(rowData.getName());
        rowVector.add(rowData.getCc());
        rowVector.add(rowData.getAge());
        rowVector.add(rowData.getPhone());
        rowVector.add(rowData.getDate());
        rowVector.add(rowData.getAmount());
        rowVector.add(rowData.getCc());

        super.addRow(rowVector);
    }

    // TODO: methods to return a row as a RowData object
}

Then you could use either the super's addRow(Vector data) method or your overload above.

Upvotes: 5

Related Questions