Java 使用AbstractTableModel在Jtable中添加行

Java 使用AbstractTableModel在Jtable中添加行,java,swing,jtable,abstracttablemodel,Java,Swing,Jtable,Abstracttablemodel,我试图在Jtable中添加一行,该行扩展了AbstractTableModel,如下代码所示: class AbstractTable extends AbstractTableModel { String[] columNames = {"name", "cc", "age", "phone", "date", "amoun"}; Object[][] dataRow = {{"harry", "1234","21","23594","13/3/2","3000"}

我试图在
Jtable
中添加一行,该行扩展了
AbstractTableModel
,如下代码所示:

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);
    }
}
在这里,我实现了一个按钮,该按钮在按下后尝试将一行添加到
Jtable
模型中,但它不起作用并引发异常:

java.lang.ClassCastException:无法将AbstractTable转换为 javax.swing.table.DefaultTableModel

如何在此代码中正确添加行

如何在此代码中正确添加行

你需要重新做你的模型。目前,您正在将数据硬编码到固定大小的数组中,这将削弱您添加数据的能力。相反:

  • 对模型的核心使用
    列表
    ,而不是对象的二维数组。请注意,RowType是您创建的一个类,用于保存行中的所有数据
  • 使用此行类型可以轻松地从每个单元格获取和设置项目。这意味着更改getValueAt和setValueAt方法以适应RowType对象
  • 为您的模型提供一个
    public void addRow(RowType rowData)
    方法,允许您将新对象添加到列表中。您不能使用DefaultTableModel的方法,因为您的模型没有扩展它,所以您必须自己编写
  • 在这个方法中,调用相应的超类的
    fireXxxx(…)
    方法
或者:不要让您的模型扩展AbstractTableModel,而是让它扩展DefaultTableModel并使用其方法。如果你这样做,你就不会让你的类持有一个2D数组,而是使用默认的自己的数据核,一个你可以通过默认的超级构造函数和方法填充和修改的数据核。您还可以创建一个addRow方法重载,该重载接受RowType类的参数

例如,假设RowData类具有字段、setter和getter以匹配列,则可以扩展DefaultTableModel,使其看起来像这样:

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
}
公共类MyTableModel扩展了DefaultTableModel{
public static final String[]COLUMN_NAMES={“name”、“cc”、“age”、“phone”、“date”、“amount”};
公共MyTableModel(){
超级(列名称,0);
}
@凌驾
公共类getColumnClass(int columnIndex){
if(getRowCount()>0&&getValueAt(0,columnIndex)!=null){
返回getValueAt(0,columnIndex).getClass();
}
返回super.getColumnClass(columnIndex);
}
public void addRow(RowData RowData){
if(rowData==null){
抛出新的IllegalArgumentException(“rowData不能为null”);
}
向量行向量=新向量();
添加(rowData.getName());
添加(rowData.getCc());
添加(rowData.getAge());
添加(rowData.getPhone());
添加(rowData.getDate());
添加(rowData.getAmount());
添加(rowData.getCc());
super.addRow(rowVector);
}
//TODO:将行作为RowData对象返回的方法
}

然后您可以使用super的
addRow(Vector data)
方法或上面的重载。

您只需正确实现
getValueAt(int,int)
。以下是一个例子:

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);
    }
}
公共类PersonTableModel扩展了AbstractTableModel{
字符串[]columnNames=新字符串[]{“姓名”、“年龄”、“地址”、“就业状态”};
列表数据=新的ArrayList();
公共PersonTableModel(){
//(使用setter方法设置人员的正确方法)
数据。添加(新人员(“Sampath”、“+94765154345”、“34”、“男性”、“加勒”、“合同”);
}
//抽象方法实现
public int getRowCount(){
返回data.size();
}
//抽象方法实现
public int getColumnCount(){
返回columnNames.length;
}
//抽象方法实现
公共对象getValueAt(整数行,整数列){
Person personObj=data.get(行);
开关(柱){
案例0:返回personObj.getName();
案例1:返回personObj.getAge();
案例2:返回personObj.getAddress();
案例3:返回personObj.getEmpStatus();
默认值:返回null;
}
}
@凌驾
公共字符串getColumnName(int列){
返回columnNames[列];
}
公共无效添加数据(个人){
数据。添加(人);
}
}

在AbstractTableModel中,有一些方法可以更新要插入的表。 将数据添加到列表中后,必须重新绘制(fireTable)表

如果您不想插入一行,则必须指定起始行和结束行相同。AbstractTableModel中还有其他更新和删除的方法,甚至可以更新单个单元格


如果我实现一个向量,而不是一个二维数组,那么它的工作原理可能与二维数组相同list@Cohen当前位置我不明白你在问什么。我自己,我会使用ArrayList,而不是Vector,但是你有什么问题吗?在你的回答中,你告诉我用一个列表来改变二维固定大小的数组,我能实现一个Vector来将Jtable数据存储到一个新方法addRow In Abstract table Model中吗?@Cohen:是的,你可以使用Vector,同样,只要您进行上述适当的更改。但是,Java诸神再次建议避免使用Vector,而是使用ArrayList,但是您可以随心所欲地使用它。
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);
    }
}
list.add(data);
fireTableRowsInserted(list.size() - 1, list.size() - 1);