2
votes

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

    }
1
Consider providing a runnable example 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 responsesMadProgrammer
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 itMadProgrammer
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 19Yunus Einsteinium
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 listMadProgrammer

1 Answers

1
votes

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
}