书接上文,如何配合ICellModifier定义合适的CellEditor?
CellEditor是所有Cell Editor的抽象基类,所有自定义的Cell Editor必须继承自这个基类;当然JFace为了方便起见,已经定义了一些子类:
1、TextCellEditor:处理简单的String;
2、ColorCellEditor:处理颜色;
3、ComboBoxCellEditor:处理从drop-down的组合框里获得数据;
4、CheckBoxCellEditor:处理布尔值;
5、DialogCellEditor:处理从对话框中获得的数据;ColorCellEditor就是DialogCellEditor的一个子类;
在日常使用中,1、3、4可以基本上满足我们的要求,但是如果我们需要处理一些比较复杂的数据类型,那么就需要自定义cell editor。我比较推荐使用DialogCellEditor,因为我们可以在这个editor中打开一个对话框,这个对话框可以包含很多控件,我们可以根据我们需要处理的数据类型组织相应的组件,在对话框中完成的操作,最终将会被保存到数据模型中,以此完成这个cell的编辑工作;
那么,从DialogCellEditor的名字我们可以看出,我们需要定义一个对话框,这里我们有两个选择:继承自org.eclipse.jface.dialogs.Dialog或者继承自org.eclipse.swt.widgets.Dialog;这两个解决方案都是可以的,不同的是,前者提供了对话框按钮,后者仅仅是一个普通的窗口需要我们自己增加响应的按钮和处理逻辑;当然后者的灵活性更强一些。
在DialogCellEditor中,我们需要重载函数:protected abstract Object openDialogBox(Control cellEditorWindow);顾名思义,系统将利用这个函数打开响应的对话框进行操作。其中参量cellEditorWindow表示了cell editor窗口的parent control;所以我们可以通过:cellEditorWindow.getShell()来获得shell变量;并把shell变量作为对话框的parent传给构造函数。
对话框需要定义一个open函数,用来打开响应的对话框,这个open函数可以参考普通的窗口打开代码,如:
public Object open() {
Shell parent = getParent();
// Your code goes here (widget creation, set result, etc).
shell.open();
Display display = parent.getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return "values of some type";
}
这样,我们就完成了相应的Dialog Cell Editor;
再罗嗦一下:
1、定义一个Dialog,继承自某一个Dialog基类;Dialog中可以包含多种组件,用来编辑一个复杂的数据模型;
2、在Dialog中定义一个open函数,如上;
3、定义一个DialogCellEditor,重载其openDialogBox函数,在此函数中调用Dialog的open函数;然后将Dialog返回值作为返回函数值;
当然,如果选择了使用CellEditor的话,TableViewer必须定义Content Provider、Label Provider、Cell Modifier,它们共同工作完成我们的需求;
当当然,如果你觉得所有以上的Cell Editor都不能满足你的要求,那么就只能从CellEditor中继承自定义子类,这时,需要重构四个函数:
1、protected abstract Control createControl(Composite parent);
2、protected abstract Object doGetValue();
3、protected abstract void doSetFocus();
4、protected abstract void doSetValue(Object value);
这属于更高级的定制,现在还没有研究;