2

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

    }
Yunus Einsteinium
  • 1,102
  • 4
  • 21
  • 55
  • 1
    Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses – MadProgrammer Jul 09 '15 at 07:11
  • If you call `model.deleteRow(row);` and then `AdvancePayment deletedPayment = payments.get(indexModel);`...what do you expect it to return? Also note, you didn't convert the `row` index to the model index before you delete it – MadProgrammer Jul 09 '15 at 07:24
  • i used index returned from tableAdvancePayment.convertRowIndexToModel(row); but still record returned is 1 less than intended e.g when 20 is selected i see 19 – Yunus Einsteinium Jul 09 '15 at 09:02
  • `this.advanceList = advanceList;` means that both the `List` in the `TableModel` and the one you past to are the same thing (they point to the same `List`), you are interacting on the same instance of the `List`, you're trying to find an entry which no longer exists. Try using `this.advanceList = new ArrayList<>(advanceList);` instead, which will make a copy of the `List`, this way when you remove an item from the `TableModel`, it won't be removed from the original list – MadProgrammer Jul 09 '15 at 13:16

1 Answers1

1

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
}  
Santhosh Kumar Tekuri
  • 3,012
  • 22
  • 22