You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:09:11