Search code examples
javaswingjtableabstracttablemodel

JTable gets wrong value in a List


I have a JTable

    id       member_id        amount
    20       1                120
    19       1                5400
    18       2                580
    17       3                620
    16       2                250

When a row is right clicked and a popupmenu item clicked, it correctly removes the row to be deleted in the JTable, but when i find the deleted record in a List of objects i used to to populate the JTable it always select next record instead.

If for example, row with id = 20 is selected, if i use the index for the JTable by using getSelectedRow to find corresponding record in the List of objects i used, i get object that matches for id = 19, and so on. When id = 16 is select, an "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException" displayed in console

I use AbstractTableModel implementation to manipulate the JTable and a List to get and populate all data in the table

My Code

    private List<AdvancePayment> payments = memberHandler.getAdvancePaidMembers();      

This is what is used when delete menuitem is clicked

    private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {                                               
          int row = tableAdvancePayment.getSelectedRow();
          model.deleteRow(row);

          int indexModel = tableAdvancePayment.convertRowIndexToModel(row);

         AdvancePayment deletedPayment = payments.get(indexModel);
          //This gets wrong record. Always return next object from the payments List
      }  

Responsible foe deleting record in List

    public void deleteRow(int index) {
          advanceList.remove(index);

          System.out.println("Row index: "+index);
          fireTableRowsDeleted(index, index);
     }        

I dont understand why the deleted index doesnot match the correct record in the same List i used to populate the database. Please assist. If you need any more code, dont hesitate to ask.

My AbstractTableModel implementation

    package TableModels;

    import java.util.List;
    import javax.swing.table.AbstractTableModel;
    import models.AdvancePayment;

    /**
     *
     * @author Administrator
     */
    public class AdvancePaymentTableModel extends AbstractTableModel{
        private List<AdvancePayment> advanceList;
        private String[] columnNames = {"MNO", "NAME", "MONTH", "ADVANCE       AMOUNT"};

        private final Class[] columnClass = new Class[] {
            Integer.class, String.class, String.class, Float.class
        };

        public AdvancePaymentTableModel(List<AdvancePayment> advanceList) {
            this.advanceList = advanceList;
        }

        @Override
        public String getColumnName(int column)
        {
            return columnNames[column];
        }

       @Override
       public Class<?> getColumnClass(int columnIndex)
       {
            return columnClass[columnIndex];
       }

       public void addRow(AdvancePayment rowData)
       {
            advanceList.add( 0, rowData );
            fireTableRowsInserted(advanceList.size() - 1, advanceList.size()   - 1);
       }

       public void deleteRow(int index) {
            advanceList.remove(index);

            System.out.println("Row index: "+index);
            fireTableRowsDeleted(index, index);
       }

       @Override
       public int getRowCount() {
           return advanceList.size();
       }

       @Override
       public int getColumnCount() {
            return columnNames.length;
       }

       @Override
       public Object getValueAt(int rowIndex, int columnIndex) {
             AdvancePayment row = advanceList.get(rowIndex);

            if(0 == columnIndex) {
                return row.getMNO();
            }
            else if(1 == columnIndex) {
                return row.getName();
            }
           else if(2 == columnIndex) {
                return getMonthString(row.getAdvanceMonth());
            }
          else if(3 == columnIndex) {
                return row.getAmountPaid();
           }
            return null;
        }

}

This is my Object model i use to make a List with

  public class AdvancePayment {
     private int member_id, advance_year, advance_month, mno;
     private long id;
     private float amount_paid;
     private String name;

     public int getMNO() {
          return mno;
     }

     public void setMNO(int mno) {
         this.mno = mno;
     }

     public int getMemberId() {
         return member_id;
     }

      public void setMemberId(int member_id) {
          this.member_id = member_id;
      }

      public int getAdvanceYear() {
          return advance_year;
      }

       public void setAdvanceYear(int advance_year) {
            this.advance_year = advance_year;
       }

       public int getAdvanceMonth() {
            return advance_month;
       }

       public void setAdvanceMonth(int advance_month) {
            this.advance_month = advance_month;
       }

       public long getId() {
           return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public float getAmountPaid() {
            return amount_paid;
        }

        public void setAmountPaid(float amount_paid) {
            this.amount_paid = amount_paid;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

Solution

  • first get the payment to be deleted, then delete it from table.

    sample implementation look as below:

    private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {                                               
          int row = tableAdvancePayment.getSelectedRow();
          AdvancePayment deletedPayment = payments.get(indexModel);
          model.deleteRow(row);
          //do something with deletedPayment
    }