如何在Java的DefaultTableModel中存入并取回Product对象?
嘿,我来帮你搞定这个问题!你当前的代码是把Product的属性拆成字符串存到表格行里,这样确实没法直接取回完整的Product对象——因为表格里只保存了这些零散的字符串,而不是对象本身。下面给你几个实用的解决方案,按推荐程度排序:
方案1:自定义TableModel(最推荐)
这种方式最符合MVC设计思想,让TableModel直接管理Product对象集合,表格显示的只是对象的属性,底层始终保存完整的Product实例。
首先,创建一个继承自AbstractTableModel的自定义模型:
import javax.swing.table.AbstractTableModel; import java.util.ArrayList; import java.util.List; public class ProductTableModel extends AbstractTableModel { private final List<Product> products; private final String[] columnNames = {"ID", "Name", "Price"}; public ProductTableModel() { this.products = new ArrayList<>(); } // 添加产品到模型 public void addProduct(Product product) { products.add(product); fireTableRowsInserted(products.size() - 1, products.size() - 1); } // 根据行索引获取Product对象 public Product getProductAt(int rowIndex) { return products.get(rowIndex); } @Override public int getRowCount() { return products.size(); } @Override public int getColumnCount() { return columnNames.length; } @Override public String getColumnName(int column) { return columnNames[column]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { Product product = products.get(rowIndex); switch (columnIndex) { case 0: return product.getId(); case 1: return product.getName(); case 2: return product.getPrice(); default: return null; } } }
然后修改你的Controller代码,使用这个自定义模型:
public class Controller { public Controller() { View view = new View(this); // 假设View里已经初始化了ProductTableModel ProductTableModel productModel = view.getProductTableModel(); Product product1 = new Product(1,"Cola",2.54); productModel.addProduct(product1); } }
之后,在任何需要取回对象的类里(比如View的事件监听中),直接调用模型的getProductAt方法:
// 比如获取选中行的Product int selectedRow = table.getSelectedRow(); if (selectedRow != -1) { Product product = productModel.getProductAt(selectedRow); // 拿到完整的Product对象,想干嘛就干嘛啦 }
方案2:用隐藏列存储完整Product对象
如果不想自定义模型,可以给默认的DefaultTableModel加一个隐藏列,专门用来存Product对象,其他列显示属性。
修改Controller的添加逻辑:
public class Controller { public Controller() { View view = new View(this); DefaultTableModel viewDtm = view.getDefaultTableModel(); // 先添加一个隐藏列(比如第3列之后) viewDtm.addColumn("ProductObject"); Product product1 = new Product(1,"Cola",2.54); // 把完整对象放到最后一列 viewDtm.addRow(new Object[]{ product1.getId(), product1.getName(), product1.getPrice(), product1 // 这里存完整对象 }); // 在View里把这个列设置为隐藏 view.getTable().removeColumn(view.getTable().getColumnModel().getColumn(3)); } }
取回对象的时候,直接从对应行的隐藏列位置获取:
// 假设拿到了选中行索引 int row = table.getSelectedRow(); if (row != -1) { // 注意:这里的列索引是你隐藏列的位置,比如刚才的第3列(从0开始) Product product = (Product) viewDtm.getValueAt(row, 3); }
方案3:用Map关联行索引和Product对象
还可以维护一个Map<Integer, Product>,把表格的行索引和对应的Product对象绑定起来。
在Controller里初始化Map:
import java.util.HashMap; import java.util.Map; public class Controller { // 全局或者在合适的作用域维护这个Map private Map<Integer, Product> rowToProductMap = new HashMap<>(); public Controller() { View view = new View(this); DefaultTableModel viewDtm = view.getDefaultTableModel(); Product product1 = new Product(1,"Cola",2.54); int rowIndex = viewDtm.getRowCount(); viewDtm.addRow(new Object[]{ product1.getId(), product1.getName(), product1.getPrice() }); // 把行索引和对象存入Map rowToProductMap.put(rowIndex, product1); } // 提供一个方法给其他类获取对象 public Product getProductByRowIndex(int rowIndex) { return rowToProductMap.get(rowIndex); } }
其他类需要取回时,调用这个方法:
// 比如在View中获取选中行 int selectedRow = table.getSelectedRow(); if (selectedRow != -1) { Product product = controller.getProductByRowIndex(selectedRow); }
内容的提问来源于stack exchange,提问作者Wesley
相关产品推荐
相关产品推荐

