使用 AbstractTableModel 在 Jtable 中添加一行
Adding a Row in a Jtable with 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"} };
@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 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 ?
您需要重新制作模型。目前,您正在对固定大小的数组中的数据进行硬编码,这会削弱您添加数据的能力。相反:
- 对模型的 核心 使用
List<RowType>
,而不是对象的二维数组。请注意,RowType 是您创建的 class,它包含一行中的所有数据。
- 使用此 RowType 可以轻松获取和设置每个单元格中的项目。这意味着更改您的 getValueAt 和 setValue at 方法以适应您的 RowType 对象。
- 为您的模型提供一个
public void addRow(RowType rowData)
方法,允许您将新对象添加到列表中。你不能使用 DefaultTableModel 的方法,因为你的模型没有扩展它,所以你必须自己写。
- 在此方法中,调用超级 class 的适当
fireXxxx(...)
方法。
或者:不要让您的模型扩展 AbstractTableModel,而是让它扩展 DefaultTableModel 并使用它的方法。如果你走这条路,你不会让你的 class 持有一个二维数组,而是会使用 Default 自己的数据核,你可以通过 Default 的超级构造函数和方法填充和修改它。您还可以创建一个 addRow 方法重载,它接受 class RowType
参数
例如假设一个 RowData class 带有字段和 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
}
然后你可以使用 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);
}
}
在 AbstractTableModel 中有一些方法可以更新 table 以进行插入。
将数据添加到列表后,必须重新绘制 (fireTable)table
list.add(data);
fireTableRowsInserted(list.size() - 1, list.size() - 1);
如果您不想插入一行,则起始行和结束行必须相同。在 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"} };
@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 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 ?
您需要重新制作模型。目前,您正在对固定大小的数组中的数据进行硬编码,这会削弱您添加数据的能力。相反:
- 对模型的 核心 使用
List<RowType>
,而不是对象的二维数组。请注意,RowType 是您创建的 class,它包含一行中的所有数据。 - 使用此 RowType 可以轻松获取和设置每个单元格中的项目。这意味着更改您的 getValueAt 和 setValue at 方法以适应您的 RowType 对象。
- 为您的模型提供一个
public void addRow(RowType rowData)
方法,允许您将新对象添加到列表中。你不能使用 DefaultTableModel 的方法,因为你的模型没有扩展它,所以你必须自己写。 - 在此方法中,调用超级 class 的适当
fireXxxx(...)
方法。
或者:不要让您的模型扩展 AbstractTableModel,而是让它扩展 DefaultTableModel 并使用它的方法。如果你走这条路,你不会让你的 class 持有一个二维数组,而是会使用 Default 自己的数据核,你可以通过 Default 的超级构造函数和方法填充和修改它。您还可以创建一个 addRow 方法重载,它接受 class RowType
参数例如假设一个 RowData class 带有字段和 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
}
然后你可以使用 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);
}
}
在 AbstractTableModel 中有一些方法可以更新 table 以进行插入。 将数据添加到列表后,必须重新绘制 (fireTable)table
list.add(data);
fireTableRowsInserted(list.size() - 1, list.size() - 1);
如果您不想插入一行,则起始行和结束行必须相同。在 AbstractTableModel 中还有其他更新和删除方法,即使是更新单个单元格