虽然在应用任何更改之前停止编辑任何和所有单元格是可行的,但这有点像使用大锤敲击坚果。例如,如果正在编辑的单元格不是被删除的单元格,会发生什么?这是您将遇到的下一个问题。出于这个原因和其他原因,有更好的方法。
首先,使用框架为您完成繁重的工作。将TableModelListener 附加到您的表模型table.getModel().addTableModelListener()... 然后在您的侦听器实现中捕获删除事件并按如下方式处理:
/**
* Implements {@link TableModelListener}. This fine grain notification tells listeners
* the exact range of cells, rows, or columns that changed.
*
* @param e the event, containing the location of the changed model.
*/
@Override
public void tableChanged(TableModelEvent e) {
if (TableModelEvent.DELETE == e.getType()) {
// If the cell or cells beng edited are within the range of the cells that have
// been been changed, as declared in the table event, then editing must either
// be cancelled or stopped.
if (table.isEditing()) {
TableCellEditor editor = table.getDefaultEditor(ViewHolder.class);
if (editor != null) {
// the coordinate of the cell being edited.
int editingColumn = table.getEditingColumn();
int editingRow = table.getEditingRow();
// the inclusive coordinates of the cells that have changed.
int changedColumn = e.getColumn();
int firstRowChanged = e.getFirstRow();
int lastRowChanged = e.getLastRow();
// true, if the cell being edited is in the range of cells changed
boolean editingCellInRangeOfChangedCells =
(TableModelEvent.ALL_COLUMNS == changedColumn ||
changedColumn == editingColumn) &&
editingRow >= firstRowChanged &&
editingRow <= lastRowChanged;
if (editingCellInRangeOfChangedCells) {
editor.cancelCellEditing();
}
}
}
}
}
在上面的示例中,我将自己的编辑器指定为表 table.setDefaultRenderer(ViewHolder.class, new Renderer()); table.setDefaultEditor(ViewHolder.class, new Editor()); 的默认编辑器。
另外,我使用ViewHolder,而不是使用特定视图。这样做的原因是为了使表格在其显示的视图方面具有通用性。这是通用的ViewHolder.class:
/**
* Holds the view in a table cell. It is used by both the {@link Renderer}
* and {@link Editor} as a generic wrapper for the view.
*/
public static abstract class ViewHolder {
private static final String TAG = "ViewHolder" + ": ";
// the position (index) of the model data in the model list
protected final int position;
// the model
protected Object model;
// the view to be rendered
protected final Component view;
// the views controller
protected final Object controller;
/**
* @param view the view to be rendered
* @param position the position (index) of the data
*/
public ViewHolder(int position,
Object model,
Component view,
Object controller) {
this.position = position;
if (view == null) {
throw new IllegalArgumentException("item view may not be null");
}
if (model == null) {
throw new IllegalArgumentException("model may not be null");
}
this.controller = controller;
this.model = model;
this.view = view;
}
现在,每次调用您的渲染器或编辑器时,构造一个ViewHolder 类并传入您的视图/控制器/位置等,就完成了。
这里要注意的重要一点是,您不必在删除或更改事件发生之前捕获它。实际上,您应该在模型更改后捕获它。为什么?发生变化之后,您就知道发生了什么变化,因为TableModelListener 会告诉您,帮助您确定下一步该做什么。