Search code examples
javaswingjtabletablerowsorter

Getting the correct row in JTable using TableRowSorter


I'm currently using a JTable with a TableRowSorter to implement a search function for the users. Below is my code

    tblDutyList = new JTable() {
        @Override
        public java.awt.Component prepareRenderer(
                TableCellRenderer renderer, int row, int col) {
            java.awt.Component comp = super.prepareRenderer(renderer, row,
                    col);
            Object value = getModel().getValueAt(row, 4);
            if (value.equals("Inactive")) {
                comp.setBackground(Color.white);
                comp.setForeground(Color.GRAY);
            } else {
                if (tblDutyList.isCellSelected(row, col)) {
                    comp.setBackground(Color.lightGray);
                    comp.setForeground(Color.BLACK);
                } else
                    comp.setBackground(Color.white);
                comp.setForeground(Color.BLACK);
            }
            return comp;
        }
    };

    tblDutyList.setFillsViewportHeight(true);
    String dutyId = "0", dutyName = "", dutyDesc = "", dutySectorName = "", dutyStatus = "", dutyRemoveReason = "";

    Duty d = new Duty(Integer.parseInt(dutyId), dutyName, dutyDesc,
            dutySectorName, dutyStatus, dutyRemoveReason);

    ArrayList<Duty> dutyResult = rdc.processRetrieveDuties(d);

    DutyModel dutyModel = new DutyModel(dutyResult);

    tblDutyList.setModel(dutyModel);
    scrollPane.setViewportView(tblDutyList);

    // sorter for search function
    sorter = new TableRowSorter<TableModel>(dutyModel);
    tblDutyList.setRowSorter(sorter);

    // customizing how the table looks
    tblDutyList.setRowHeight(100);
    tblDutyList.getColumnModel().getColumn(0)
            .setCellRenderer(new MyCellRenderer());
    tblDutyList.getColumnModel().getColumn(1)
            .setCellRenderer(new MyCellRenderer());
    tblDutyList.getColumnModel().getColumn(2)
            .setCellRenderer(new MyCellRenderer());
    tblDutyList.getColumnModel().getColumn(3)
            .setCellRenderer(new MyCellRenderer());
    tblDutyList.getColumnModel().getColumn(4)
            .setCellRenderer(new MyCellRenderer());
    tblDutyList.getColumnModel().getColumn(5)
            .setCellRenderer(new MyCellRenderer());

where the JTable will load all my duties from the database. Afterwhich, the user can select a row from the table and perform some tasks like assign, update, and delete. However, my problem is, when I use the filter function, the user will get the wrong record, for example the first duty is "cleaning the windows", and the second one is "sweeping the floor", and I filter out "sweeping the floor" which will then render "sweeping the floor" as the record right on top of the table. The user selects the result ("sweeping the floor") and presses any of the actionPerform, and will be redirected to get "cleaning the windows" instead, since that's originally the first value. This is my a part of actionPerformed code:

            if (tblDutyList.getSelectedRow() != -1) {                   
                int rowIndex = tblDutyList.getSelectedRow();
                int idDuty = (int) tblDutyList.getModel().getValueAt(
                        rowIndex, 0);
                String name = (String) tblDutyList.getModel().getValueAt(
                        rowIndex, 1);
                String desc = (String) tblDutyList.getModel().getValueAt(
                        rowIndex, 2);
                String sector = (String) tblDutyList.getModel().getValueAt(
                        rowIndex, 3);

                String status = (String) tblDutyList.getModel().getValueAt(
                        rowIndex, 4);

This probably means that my actionPerformed will get the value at the specific location instead of reading the values before my user is redirected. Any help is greatly appreciated. Thanks in advance!!


Solution

  • You will want to use one of the JTable's conversion methods...

    This will allow you to convert between what the view and model thinks the row value means, for example...

    int rowIndex = tblDutyList.getSelectedRow();
    rowIndex = tblDutyList.convertRowIndexToModel(rowIndex);
    int idDuty = (int) tblDutyList.getModel().getValueAt(
                        rowIndex, 0);
    

    Take a closer look at

    For more details...