Hi,
I have a big problem when using the CheckBoxCellEditor in a NatTable with a couple of thousand rows. The Nattable is used in an RCP application. This is what happens:
I have a column that uses the CheckBoxCellEditor for editing. When I select the column (with a large number of rows about 9000 in my case) and press space to change the boolean value, the application freezes the next time the Nattable is refreshed. I have tackled down the problem to the activateCell method of the editor.
protected Control activateCell(Composite parent,
Object originalCanonicalValue) {
// if this editor was activated by clicking a letter or digit key, do
// nothing
if (originalCanonicalValue instanceof Character) {
return null;
}
setCanonicalValue(originalCanonicalValue);
this.checked = !this.checked;
this.canvas = createEditorControl(parent);
commit(MoveDirectionEnum.NONE, false);
if (this.editMode == EditModeEnum.INLINE) {
// Close editor so will react to subsequent clicks on the cell
if (this.canvas != null && !this.canvas.isDisposed()) {
this.canvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
close();
}
});
}
}
return this.canvas;
}
This code is called number of rows time from the edit controller. Each time an editor is created. In our case the editor is represented by a Canvas. So after setting the value to 9000 cells we have 9000 Canvases as children of the Nattable. The next time the table gets painted, the org.eclipse.e4.ui.css.swt.engine.CSSSWTEngine of Eclipse applies it's styles to the NatTable and all it's children. I am not sure but this might happen 9000 times for each canvas that was created and is then disposed in the async excec of the code shown above. In any case the application is not usable for a very long time.
A solution is to create the editor only once and reuse it for consecutive calls to activate.
protected Control activateCell(Composite parent,
Object originalCanonicalValue) {
// if this editor was activated by clicking a letter or digit key, do
// nothing
if (originalCanonicalValue instanceof Character) {
return null;
}
setCanonicalValue(originalCanonicalValue);
this.checked = !this.checked;
if (canvas == null || canvas.isDisposed()) {
this.canvas = createEditorControl(parent);
if (this.editMode == EditModeEnum.INLINE) {
// Close editor so will react to subsequent clicks on the cell
if (this.canvas != null && !this.canvas.isDisposed()) {
this.canvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
close();
}
});
}
}
}
commit(MoveDirectionEnum.NONE, false);
return this.canvas;
}
This works but the question is if there are any obvious drawbacks with this solution which I might be missing here.
Thanks in advance
Thorsten