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注入风险
额外优化建议
- 数据库连接复用:每次编辑都新建连接会拖慢性能,建议用连接池(比如HikariCP)来复用数据库连接
- 异步加载:如果数据库查询耗时较长,同步加载会导致UI卡顿,可以用
SwingWorker在后台线程执行查询,加载完成后再更新ComboBox选项 - 异常友好提示:把控制台打印的异常换成弹窗提示,让用户更直观地知道出了什么问题
内容的提问来源于stack exchange,提问作者HAAS BOOSTED
相关产品推荐
相关产品推荐

