JTable搜索后删除选中行异常:误删原始首行问题求助
JTable搜索后删除行异常问题解决
问题场景
JTable默认展示所有人员姓名,在文本框输入关键词搜索后,表格仅显示匹配的单条数据。点击该行并点击删除按钮时,并未删除该匹配数据,反而删除了搜索前表格的首行。
用户提供代码
删除按钮关联代码
private void officialsDelete() { DefaultTableModel RecordTable = (DefaultTableModel)officialTable.getModel(); int SelectedRows = officialTable.getSelectedRow(); try{ if(officialTable.getSelectedRowCount() == 1){ id = Integer.parseInt(RecordTable.getValueAt(SelectedRows, 0).toString()); deleteItem = JOptionPane.showConfirmDialog(null, "Confirm if you want to delete item", "Warning",JOptionPane.YES_NO_OPTION); if(deleteItem == JOptionPane.YES_OPTION){ Class.forName("com.mysql.cj.jdbc.Driver"); sqlConn = DriverManager.getConnection(dataConn,username,password); pst = sqlConn.prepareStatement("delete from officials where id =?"); RecordTable.removeRow(officialTable.getSelectedRow()); pst.setInt(1, id); pst.executeUpdate(); JOptionPane.showMessageDialog(this,"Recorded Updated"); upDateDBOfficials(); } }else{ if(officialTable.getRowCount()==0){ JOptionPane.showMessageDialog(this,"Table is Empty!"); }else{ JOptionPane.showMessageDialog(this,"Please select Single row for Deleting"); } } }catch(ClassNotFoundException ex){ java.util.logging.Logger.getLogger(InformationSystem.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); }catch(SQLException ex){ java.util.logging.Logger.getLogger(InformationSystem.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } }
搜索文本框keyReleased事件代码
private void officialsSearch() { String search = officialSearchTxt.getText(); DefaultTableModel model = (DefaultTableModel)officialTable.getModel(); TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<>(model); officialTable.setRowSorter(sorter); sorter.setRowFilter(RowFilter.regexFilter("(?i)" + search)); }
问题原因
当使用TableRowSorter做行过滤后,JTable的视图行号和模型行号不再一一对应。officialTable.getSelectedRow()返回的是当前视图中选中行的索引,而直接用这个索引去操作DefaultTableModel(比如getValueAt、removeRow),会访问到模型中对应原位置的行,而非过滤后视图里的选中行,这就导致删错了数据。
解决方法
使用JTable.convertRowIndexToModel(int viewRow)方法,将视图行号转换成对应的模型行号,再用模型行号操作数据模型。
修改后的删除按钮代码
private void officialsDelete() { DefaultTableModel RecordTable = (DefaultTableModel) officialTable.getModel(); // 获取视图选中行号 int viewSelectedRow = officialTable.getSelectedRow(); try { if (officialTable.getSelectedRowCount() == 1) { // 转换为模型行号 int modelSelectedRow = officialTable.convertRowIndexToModel(viewSelectedRow); // 用模型行号获取id id = Integer.parseInt(RecordTable.getValueAt(modelSelectedRow, 0).toString()); int deleteItem = JOptionPane.showConfirmDialog(null, "确认是否删除该条目", "警告", JOptionPane.YES_NO_OPTION); if (deleteItem == JOptionPane.YES_OPTION) { Class.forName("com.mysql.cj.jdbc.Driver"); sqlConn = DriverManager.getConnection(dataConn, username, password); pst = sqlConn.prepareStatement("delete from officials where id =?"); // 用模型行号删除模型中的行 RecordTable.removeRow(modelSelectedRow); pst.setInt(1, id); pst.executeUpdate(); JOptionPane.showMessageDialog(this, "记录已更新"); upDateDBOfficials(); // 关闭资源,避免连接泄漏 pst.close(); sqlConn.close(); } } else { if (officialTable.getRowCount() == 0) { JOptionPane.showMessageDialog(this, "表格为空!"); } else { JOptionPane.showMessageDialog(this, "请选择单行进行删除"); } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(InformationSystem.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (SQLException ex) { java.util.logging.Logger.getLogger(InformationSystem.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } }
额外优化(搜索事件)
每次输入都创建新的TableRowSorter会造成不必要的开销,可以复用已有的RowSorter:
// 在类中定义成员变量保存sorter private TableRowSorter<DefaultTableModel> officialTableSorter; private void officialsSearch() { String search = officialSearchTxt.getText(); DefaultTableModel model = (DefaultTableModel) officialTable.getModel(); if (officialTableSorter == null) { officialTableSorter = new TableRowSorter<>(model); officialTable.setRowSorter(officialTableSorter); } if (search.trim().isEmpty()) { officialTableSorter.setRowFilter(null); // 清空过滤,显示所有行 } else { officialTableSorter.setRowFilter(RowFilter.regexFilter("(?i)" + search)); } }
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

