Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JTable removal of currently edited object.

843807Aug 29 2009 — edited Aug 29 2009
Hello,

I have the following problem with JTable: I'm using it to display and edit a list of objects. The objects may be edited via the cells in the JTable. More specifically I have an object ShapeTableModel that implements TableModel and extends ArrayList. I've overridden the add and remove methods to also signal any registered TableModelListeners (see the first code below). I've also implemented a removal Action (second bit of code below) which removes the selected elements of the JTable.

All this works fine except for the case where I am removing a ShapeHandler object that is also currently being edited in the JTable. The underlying ShapeHandler object in the TableModel will be removed, as well as the corresponding row in the table. The problem occurs when I now try to change the selection of the JTable. Before the valueChanged method of the ListSelectionListener is fired the JTable produces an IndexOutOfBounds exception because as far as I can make out it thinks it ought to finish the editing process. The edited object has been removed however causing the IOOBE. My question now is, how can I avoid this (if this is at all possible).

Kind Regards,
Lukas
public class ShapeTableModel extends ArrayList<ShapeHandler> implements TableModel, ShapeChangeListener {
	private static Logger log = Logger.getLogger(ShapeTableModel.class.getName());
	
	String[] headers = { "Type", "Mass", "Centre X", "Centre Y", "Radius/Rotation", "Width", "Height", "Fix" };
	Class<?>[] classes = {String.class, Float.class, Float.class, Float.class, Float.class, Float.class, Float.class, Boolean.class};
	/**
	 * Used to determine table dimensions
	 */
	public Object[] longValues = {"Circle",1000, 1000,1000,1000,1000,1000,false};

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

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

	@Override
	public String getColumnName(int columnIndex) {
		return headers[columnIndex];
	}

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

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		return get(rowIndex).getValueAt(columnIndex);
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		//first column is not editable
		if (columnIndex == 0) return false;
		return true;
	}
	@Override
	public void setValueAt(Object value, int rowIndex, int columnIndex) {
		get(rowIndex).setValueAt(columnIndex, value);
	}

	@Override
	public boolean add(ShapeHandler e) {
		super.add(e);
		e.addSCL(this);
		TableModelEvent tme = new TableModelEvent(this);
		signalListeners(tme);
		return true;
	}
	
	@Override
	public ShapeHandler remove(int index) {
		ShapeHandler r = super.remove(index);
		
		TableModelEvent tme = new TableModelEvent(this);
		signalListeners(tme);
		return r;
	}
	
	// -------Listener relevant code-----------------
	Set<TableModelListener> listeners = new HashSet<TableModelListener>(1);
	private void signalListeners(TableModelEvent e) {
		for (TableModelListener l : listeners) {
			l.tableChanged(e);
		}
	}
	@Override
	public void addTableModelListener(TableModelListener l) {
		listeners.add(l);
	}
	@Override
	public void removeTableModelListener(TableModelListener l) {
		listeners.remove(l);
	}

	@Override
	public void shapeChanged(Shape s) {
		int i = indexOf(s);
		TableModelEvent tme = new TableModelEvent(this, i);
		signalListeners(tme);
	}
}
JTable table = new JTable();
ShapeTableModel model;
...initialised in constructor
...
private class RemAction extends AbstractAction {
	public RemAction() {
		super("Remove");
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		removeSelected();
	}
}
...
public void removeSelected() {
	int[] inds = table.getSelectedRows();
	removeShapes(inds);
}

private void removeShapes(int[] indices) {
	Arrays.sort(indices);
	int mod = 0;
	for (int i = 0; i < indices.length; i++) {
		model.remove(indices[i] - mod);
		mod++;
	}
}
...
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 26 2009
Added on Aug 29 2009
4 comments
126 views