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

Java中JTable行内JComboBox数据库取值重复问题求助

解决JTable中动态JComboBox的重复添加与行内容串问题

你的问题根源其实很清晰:

  • 每次点击ComboBox时没有清空已有选项,导致重复追加相同内容
  • 所有行共用同一个ComboBox编辑器,切换行时没有重新加载对应行的专属选项

下面是修复后的完整方案,还顺便帮你优化了SQL注入的安全问题:

步骤1:用自定义TableCellEditor实现动态加载

我们不再依赖鼠标监听这种非标准方式,而是通过TableCellEditor的getTableCellEditorComponent方法来动态获取当前行数据并加载选项,这是Swing表格编辑器的标准用法:

// 替换原来的ComboBox编辑器代码
TableColumn sportColumn = table.getColumnModel().getColumn(3);
sportColumn.setCellEditor(new DefaultCellEditor(new JComboBox()) {
    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        JComboBox comboBox = (JComboBox) super.getTableCellEditorComponent(table, value, isSelected, row, column);
        
        // 第一步:先清空ComboBox的所有旧选项,避免重复添加
        comboBox.removeAllItems();
        
        // 获取当前行的第1、2列数据
        String OFNUPK = (String) table.getValueAt(row, 1);
        String TFCCMP = (String) table.getValueAt(row, 2);
        
        // 校验数据有效性后再查询数据库
        if (TFCCMP != null && !TFCCMP.isEmpty() && OFNUPK != null && !OFNUPK.isEmpty()) {
            try {
                int OFNUP = Integer.parseInt(OFNUPK);
                // 使用PreparedStatement替代字符串拼接,彻底避免SQL注入风险
                String sql = "SELECT DISTINCT a.TFCPAI FROM $$CLI00F55.FOFFAN a, SICGA00F55.FORFAB f WHERE " +
                        "a.TFCCMP = ? AND f.OFNUPK = ? AND f.OFNUPK = a.TFSNOF";
                
                // 使用try-with-resources自动关闭连接、语句和结果集,避免资源泄漏
                try (Connection con = DriverManager.getConnection("jdbc:as400://" + host, user, pwd);
                     PreparedStatement stmt = con.prepareStatement(sql)) {
                    
                    stmt.setString(1, TFCCMP);
                    stmt.setInt(2, OFNUP);
                    
                    try (ResultSet rs = stmt.executeQuery()) {
                        while (rs.next()) {
                            comboBox.addItem(rs.getString(1));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    // 这里可以换成更友好的用户提示,比如JOptionPane.showMessageDialog(null, "加载选项失败")
                }
            } catch (NumberFormatException e) {
                // 处理OFNUPK不是有效整数的情况
                e.printStackTrace();
            }
        }
        
        // 恢复当前单元格原本选中的值(如果有的话)
        if (value != null) {
            comboBox.setSelectedItem(value);
        }
        
        return comboBox;
    }
});

为什么这样能解决你的问题?

  • 避免重复添加:每次进入编辑状态时,先调用comboBox.removeAllItems()清空旧选项,再重新加载当前行对应的内容
  • 解决行内容串的问题:每一行进入编辑时,都会重新执行getTableCellEditorComponent方法,根据当前行的1、2列值加载专属选项,不再共用同一组内容
  • 安全性提升:用PreparedStatement替换字符串拼接,彻底杜绝SQL注入风险

额外优化建议

  1. 数据库连接复用:每次编辑都新建连接会拖慢性能,建议用连接池(比如HikariCP)来复用数据库连接
  2. 异步加载:如果数据库查询耗时较长,同步加载会导致UI卡顿,可以用SwingWorker在后台线程执行查询,加载完成后再更新ComboBox选项
  3. 异常友好提示:把控制台打印的异常换成弹窗提示,让用户更直观地知道出了什么问题

内容的提问来源于stack exchange,提问作者HAAS BOOSTED

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:32:59