在 JTable 中使用 Search Filter 和 mouseClicked Event 时出现的问题

Issues when Search Filter and mouseClicked Event used in JTable

此代码提供了带有 SearchFilter 的员工详细信息 JTable。 在 Employee Processing 和 Employee Processed Columns 上使用鼠标单击,它应该被定向到与当前行中的员工相关的 url。 下面的代码工作正常,除非使用搜索过滤器。 当我使用搜索过滤器并在过滤行上单击鼠标时,它会指向 JTable 第一行中与员工详细信息相关的 URL,而不是当前过滤行的员工详细信息。 有人可以帮我解决这个问题吗?

package Test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import EmployeeDAO;
import EmployeeDTO;
import common.UIConstants;

public class EmpDataWin extends JFrame {

    private static final String EMPLOYEE_NAME = "Employee Name";
    private static final String DEPARTMENT = "Department";
    private static final String DETAILS = "Details";
    private static final String EMPLOYEE_PROCESSING = "Employee Processing";
    private static final String EMPLOYEE_PROCESSED = "Employee Processed";

    private final int DETAILS_COLUMN_INDEX = 2;
    private final int EMPLOYEE_PROCESSING_COLUMN_INDEX = 3;
    private final int EMPLOYEE_PROCESSED_COLUMN_INDEX = 4;

    DefaultTableModel model = new DefaultTableModel();
    Container cont = this.getContentPane();
    JTable tab = new JTable(model);
    private TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(model);
    private final JTextField searchFilter = new JTextField();

    public EmpDataWin(List<EmployeeDTO> pEmployeeDTO) {
        initialize(pEmployeeDTO);
    }

    public void initialize(List<EmployeeDTO> pEmployeeDTOList) {

        JPanel panelParent = new JPanel(new BorderLayout());

        // Add Header

        model.addColumn(EMPLOYEE_NAME);
        model.addColumn(DEPARTMENT);
        model.addColumn(DETAILS);
        model.addColumn(EMPLOYEE_PROCESSING);
        model.addColumn(EMPLOYEE_PROCESSED);


        // Add data row to table

        for (EmployeeDTO aEmployeeDTO : pEmployeeDTOList) {
            model.addRow(new Object[] { aEmployeeDTO.getEmployee_Name(), aEmployeeDTO.getDepartment(),
                    aEmployeeDTO.getDetails(), aEmployeeDTO.getEmployee_Processing(),
                    aEmployeeDTO.getEmployee_Processed()
            });
        }

        tab.setRowSorter(rowSorter);
        tab.setAutoCreateRowSorter(true);


        JPanel panel = new JPanel(new BorderLayout());
        panel.add(new JLabel(UIConstants.SEARCH), BorderLayout.WEST);
        JTextField searchFilter = SearchFilter.createRowFilter(tab);
        panel.add(searchFilter, BorderLayout.CENTER);
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));



        tab.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Mouse listener part
        tab.addMouseListener(new MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent e) {
                int col = tab.getSelectedColumn();
                int row = tab.getSelectedRow();

                // Employee Processing columnindex is
                if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
                    String employeeName = (String) tab.getModel().getValueAt(row, col);

                    System.out.println("employeeName = " + employeeName);
                    if (employeeName != null && !employeeName.trim().equals("")) {
                        OpenURL open = new OpenURL();
                        open.openEmployeeProcessing(employeeName);
                    } else {
                        System.out.println("ERROR : Invalid Client name ....");

                    }else if(EMPLOYEE_PROCESSED_COLUMN_INDEX == col) {

                        String employeeName = (String) tab.getModel().getValueAt(row, col);

                        System.out.println("employeeName = " + employeeName);
                        if (employeeName != null && !employeeName.trim().equals("")) {
                            OpenURL open = new OpenURL();
                            open.openEmployeeProcessed(employeeName);
                        } else {
                            System.out.println("ERROR : Invalid Client name ....");


                        } else if (DETAILS_COLUMN_INDEX == col) {

                            String CD = (String) tab.getModel().getValueAt(row, col);
                            OpenDrive od = new OpenDrive();
                            osd.openDetails(CD);
                        }
                    }
                });


        tab.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        JScrollPane sp = new JScrollPane(tab,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        panelParent.add(panel,BorderLayout.NORTH);
        panelParent.add(sp,BorderLayout.CENTER);
        panelParent.setBorder(BorderFactory.createEmptyBorder(10 , 10, 10, 10));
        cont.add(panelParent);
        this.pack();

            }

            public static void main(String[] args) {

                EmployeeDAO dao = new EmployeeDAO();
                List<EmployeeDTO> dto = dao.getemployeeData();

                JFrame frame = new EmpDataWin(dto);
                frame.setTitle("Employee Data");
                frame.setLocationRelativeTo(null);
                frame.setSize(1200, 600);
                frame.setVisible(true);
            }
    }
int col = tab.getSelectedColumn();
int row = tab.getSelectedRow();

// Employee Processing columnindex is
if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
    String employeeName = (String) tab.getModel().getValueAt(row, col);

当您在 table 上使用 Sorter/Filter 时,数据不是来自 TableModel 的 sorted/removed。您只能看到数据的 sorted/filtered 视图。因此,您不再具有 "table row" 和 "model row".

的一对一映射

因此您需要使用 JTable:

的方法访问数据
    //String employeeName = (String) tab.getModel().getValueAt(row, col);
    String employeeName = (String) tab.getValueAt(row, col);

JTablegetValueAt(...) 方法将自动转换 row/column 索引以映射到 TableModel 中的适当数据,然后它将调用 getValueAt(...)方法TableModel给你。

阅读 JTable API 您会发现 4 个 convert???(...) 方法可以在模型和视图之间转换 row/column 索引,如果您需要进行这种转换手动。

您还需要修复您尝试从 TableModel 访问数据的其他地方。