JTable排序后点击表头误触发选中行弹窗问题求助
问题:JTable排序时误触发选中行弹窗
实现JTable点击行读取数据功能时遇到异常:点击某行后,再点击表头执行排序操作,会触发之前选中行的弹窗,如同再次点击该行。
现有代码
private void showUsersListInTable() { scrollPane.setVisible(true); scrollPane.getViewport().setSize(600, 500); userListTable.setSize(600, 500); getDataFromDB(); reFreshTableData(); tableModel = new DefaultTableModel(tableData, columnNames); userListTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); userListTable.setAutoCreateRowSorter(true); userListTable.setRowSelectionAllowed(true); userListTable.getSelectionModel().addListSelectionListener(e -> { if (!e.getValueIsAdjusting() && userListTable.getSelectedRow() != -1) { int a = userListTable.convertRowIndexToModel(userListTable.getSelectedRow()); String email = userListTable.getModel().getValueAt(a, 2).toString(); int i = 0; while (!users.get(i).getEmail().equals(email)) { i++; } User modifyUser = (i > users.size() || i < 0) ? new User("", "", "", "", 0, new UserRight(false, false)) : users.get(i); createDialog(modifyUser, frame); } }); scrollPane.setViewportView(userListTable); }
已尝试的无效操作
- 尝试设置JTable表头(报错,IDE显示红色下划线)
- 修改判断条件为
if(userListTable.getSelectedRow() != 0)(无效果)
解决方法
改用MouseListener监听鼠标点击事件,仅在用户点击表格数据行(非表头区域)时触发弹窗逻辑,从根源避免排序操作误触发:
private void showUsersListInTable() { scrollPane.setVisible(true); scrollPane.getViewport().setSize(600, 500); userListTable.setSize(600, 500); getDataFromDB(); reFreshTableData(); tableModel = new DefaultTableModel(tableData, columnNames); userListTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); userListTable.setAutoCreateRowSorter(true); userListTable.setRowSelectionAllowed(true); // 替换原选择监听器为鼠标点击监听器 userListTable.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { // 获取点击位置对应的行索引 int viewRow = userListTable.rowAtPoint(e.getPoint()); if (viewRow != -1) { // 转换为模型行索引(适配排序后的视图) int modelRow = userListTable.convertRowIndexToModel(viewRow); String email = userListTable.getModel().getValueAt(modelRow, 2).toString(); int i = 0; while (!users.get(i).getEmail().equals(email)) { i++; } // 修正索引越界判断逻辑 User modifyUser = (i >= users.size() || i < 0) ? new User("", "", "", "", 0, new UserRight(false, false)) : users.get(i); createDialog(modifyUser, frame); } } }); scrollPane.setViewportView(userListTable); }
说明
- 表头点击触发排序时,不会触发表格行的鼠标点击事件,因此不会误执行弹窗逻辑
- 通过
rowAtPoint(e.getPoint())准确判断点击区域是否为数据行,确保只有用户主动点击行时才执行后续操作 - 保留了
convertRowIndexToModel方法,保证排序后仍能正确获取模型中的数据
内容的提问来源于stack exchange,提问作者Norbert Kunszt
相关产品推荐
相关产品推荐

