javaswingawttablerowsorterrowsorter

Issues when Search Filter and mouseClicked Event used in JTable


This code gives the Employee Details JTable With SearchFilter. With mouseClick on the Employee Processing and Employee Processed Columns it should be directed to the url related to employee in the current row. Below code is working correctly Except when search filter is used. When I use search filter and click the mouse on filtered row then it is directing to the URL related to employee details in first row of the JTable instead of employee details current filtered row. Can someone help me with this.

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);
            }
    }

Solution

  • 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);
    

    When you use a Sorter/Filter on the table the data is not sorted/removed from the TableModel. You only see the sorted/filtered view of the data. Therefore you no longer have a one-to-one mapping of the "table row" and the "model row".

    So you need to access the data using methods of the JTable:

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

    The getValueAt(...) method of the JTable will automatically convert the row/column indexes to map to the appropriate data in the TableModel and it will then invoke the getValueAt(...) method of the TableModel for you.

    Read the JTable API you will find 4 convert???(...) methods that will convert the row/column indexes between the model and view should you ever need to do this conversion manually.

    You will also need to fix the other places where you try to access the data from the TableModel.