Before I waste any of your time I would like to go ahead and just say that I have searched through the forum using "delete row from Jtable" as the search keywords and while I have found very closely related issues, they have not solved my problem. I have found code postings by carmickr and his arguments as to why we should use DefaultTableModel instead of having created our own custom TableModel, and while I do agree, I just am not quite confident enough in applying it to my scenario. See I am reading from a file a bunch of Contractor objects and I am stuffing it into an arraylist which I am using in the following code posting to populate my TableModel which the JTable object in the gui then uses.
My problem is that everything works except when I delete and when I delete I understand that the index is changing because I just removed a row from the arraylist object. Suppose I have 33 rows displaying in the GUI. Now after I delete say row #23, the delete function works and dutifuly the row disappears from the table, but if I try to delete a row say...the last row, it does not work and throws me an IndexOutOfBoundsException which totally makes sense. My question is how do I go about fixing it? Do I have to do something with the setRowCount method?
Any help is appreciated.
Cheers,
Surya
/*
* ContractorTableModel.java
*
* Created on January 12, 2006, 11:59 PM
*
*/
package code.suncertify.gui;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.swing.table.AbstractTableModel;
import code.suncertify.db.Contractor;
/**
*
* @author Surya De
* @version 1.0
*/
public class ContractorTableModel extends AbstractTableModel {
/**
* The Logger instance. All log messages from this class are routed through
* this member. The Logger namespace is <code>sampleproject.gui</code>.
*/
private Logger log = Logger.getLogger("code.gui");
/**
* An array of <code>String</code> objects representing the table headers.
*/
private String [] headerNames = {"Record Number", "Contractor Name",
"Location", "Specialties","Size", "Rate",
"Owner"};
/**
* Holds all Contractor instances displayed in the main table.
*/
private ArrayList <Object> contractorRecords = new ArrayList<Object>(5);
/**
* Returns the column count of the table.
*
* @return An integer indicating the number or columns in the table.
*/
public int getColumnCount() {
return this.headerNames.length;
}
/**
* Returns the number of rows in the table.
*
* @return An integer indicating the number of rows in the table.
*/
public int getRowCount() {
return this.contractorRecords.size();
}
/**
* Gets a value from a specified index in the table.
*
* @param row An integer representing the row index.
* @param column An integer representing the column index.
* @return The object located at the specified row and column.
*/
public Object getValueAt(int row, int column) {
Object [] temp = (Object[]) this.contractorRecords.get(row);
return temp[column];
}
/**
* Sets the cell value at a specified index.
*
* @param obj The object that is placed in the table cell.
* @param row The row index.
* @param column The column index.
*/
public void setValueAt(Object obj, int row, int column) {
Object [] temp = (Object []) this.contractorRecords.get(row);
temp [column] = obj;
}
/**
* Returns the name of a column at a given column index.
*
* @param column The specified column index.
* @return A String containing the column name.
*/
public String getColumnName(int column) {
return headerNames[column];
}
/**
* Given a row and column index, indicates if a table cell can be edited.
*
* @param row Specified row index.
* @param column Specified column index.
* @return A boolean indicating if a cell is editable.
*/
public boolean isCellEditable(int row, int column) {
return false;
}
/**
* Adds a row of Contractor data to the table.
*
* @param specialty
* @param recNo The record number of the row in question.
* @param name The name of the contractor.
* @param location Where the contractor is located
* @param size Number of workers for the contractor
* @param rate The contractor specific charge rate
* @param owner Name of owner
*/
public void addContractorRecord(int recNo, String name,
String location, String specialty,
int size, float rate, String owner) {
Object [] temp = {new Integer(recNo), name,
location, specialty, new Integer(size),
new Float(rate), owner};
this.contractorRecords.add(temp);
fireTableDataChanged();
}
/**
* Adds a Contractor object to the table.
*
* @param contractor The Contractor object to add to the table.
*/
public void addContractorRecord(Contractor contractor) {
Object [] temp = {new Integer(contractor.getRecordNumber()),
contractor.getName(), contractor.getLocation(),
contractor.getSpecialties(), new Integer(contractor.getSize()),
new Float(contractor.getRate()), contractor.getCustomerID()};
this.contractorRecords.add(temp);
fireTableDataChanged();
}
/**
* Deletes a row of Contractor data to the table.
* @FIXME Now that I deleted a row then I will have to reset the internal structure so that I can delete again
* @param recNo The record number of the row in question.
*/
public void deleteContractorRecord(int recNo) {
contractorRecords.remove(recNo - 1);
fireTableRowsDeleted(recNo -1, recNo - 1);
}
}