JFace 可编辑的TreeViewer和TableViewer 的深度解析定义自己的CellEditor ????定义自己的CellEditor其实不
JFace 可编辑的TreeViewer和TableViewer 的深度解析
定义自己的CellEditor ????定义自己的CellEditor其实不难,完整的实例可以看Eclipse的TextCellEditor与ComboBoxCellEditor(原理都差不多,但推荐看CmboboxCellEditor,它的实现简单些)
?? 在具体实现前先说说CellEditor的原理:
?? 在点击Table或Tree的一个Cell(单元格)或Item(节点)时激发CellEditor,如果这个CellEditor是TextCellEditor这返回一个Text供User编辑,如果
是ComboBoxCellEditor则返回一个Combo供User选择,如果是自定义的CellEditor则需要在CellEditor里返回一个Control
(实现父类的createControl(Composite parent)方法。
?? 下面说说一个CellEditor具体的实现:
?? 1.首先,需要继承CellEditor类,从而实现它的几个方法。
????? 1)实现一个参数为org.eclipse.swt.widgets.Composite的构造方法,并在构造方法中调用参数为org.eclipse.swt.widgets.Composite的父类的构造方法。
????? 2)重写父类的createControl(Composite parent),需要返回我们自定义的一个Contrl,比如说Button,Text,Combo,DateTime,List,Table(当然你的Cell要够大才显美观)。
????? 3)重写父类的doSetValue(Object value),其中的value是从Table(Tree)中一个Cell(Item)上获得的值,可以用这个值为我们自定义的Control赋初值(就是当CellEditor被激活时出现的Control上显示的值)。
????? 4)重写父类的doGetValue()方法,return一个Object,这个Object是返回一个值给Table(Tree),然后Table(Tree)对这个值进行解析,再反映到对应的Cell(Item)上。
????? 5)重写父类的doSetFocus()方法,当CellEditor被激活时,把foucus显示的Control,一般用control的setFocus方法即可。
??? ok,实现自定义的CellEditor大体就是这样。
首先把TableColumn的名称做成String数组,调用viewer.setColumnProperties()方法
然后做一个CellEditor数组,数组中的每一个CellEditor都对应着每一个Column
然后实现ICellModifier接口,做一个自己的CellModifier,并调用viewer.setCellModifier()方法
接口中有三个方法:
1.public boolean canModify(Object element, String property)
用来判断哪一个属性可写
2.public Object getValue(Object element, String property)
返回某个属性的值
3.public void modify(Object element, String property, Object value)
为某个属性赋值
向已有的TreeViewer和TableViewer上添加编辑功能,可以使用CellEditor和CellModifier。
CellEditor定义了某个列被编辑时显示的外观,它可以是文本框、下拉列表框或单选框,也可以自己定义。
通常使用的CellEditor的子类就是:CheckboxCellEditor、ComboBoxCellEditor和TextCellEditor。
CellEditor一般用数组来保存,如果某个列不需要编辑,则可将该列的CellEditor设为null。
当CellEditor的数组定义完后,即可利用setCellEditors(CellEditor[] editors)方法将该数组设置到对应的TreeViewer或TableViewer中去。例如:
????CellEditor[]?cellEditors? = ? new ?CellEditor[ 5 ];
????cellEditors[ 0 ]? = ? new ?TextCellEditor(tableViewer.getTable());
????cellEditors[ 1 ]? = ? null ;
????cellEditors[ 2 ]? = ? new ?ComboBoxCellEditor(tableViewer.getTable(),? new ?String[]{ " first " ,? " second " ,? " third " ,? " forth " });
????cellEditors[ 3 ]? = ? new ?CheckboxCellEditor(tableViewer.getTable());
????cellEditors[ 4 ]? = ? new ?CustomizedTextCellEditor(tableViewer.getTable());
????tableViewer.setCellEditors(cellEditors);
其中CustomizedTextCellEditor是自定义的CellEditor,避免了设置value时造成的空指针异常。
protected?class?CustomizedTextCellEditor?extends?TextCellEditor{
????public?CustomizedTextCellEditor(Composite?parent){
????????super(parent);
????}
????protected?void?doSetValue(Object?value)?{
????????if(value?==?null)
????????????return;
????????super.doSetValue(value);
????}????????
}
CellEditor负责外观,它对要编辑的模型信息一无所知。所以jface中引入了ICellModifier接口,将model与CellEditor联系在一起。为了确定在CellModifier中的列,需要定义columnProperties的String[]数组,用以区分不同列对应的不同属性。使用setColumnProperties(String[] columnProperties)设置该属性集。
ICellModifier定义了三个接口方法:
public boolean canModify(Object element, String property);
该方法判断何时该列可以被编辑。其中element是对应的model。返回true表示此时该列可以被编辑。
public Object getValue(Object element, String property);
该方法一般在activateCellEditor()时调用,用于设定CellEditor的初始值。其中element是对应的model。
此处虽然可以返回Object类型的引用,但是使用时需小心,特定的CellEditor仅接受特定类型的Value。比如:
TextCellEditor对应String类型的Value;
ComboBoxCellEditor对应Integer类型的Value;
CheckBoxCellEditor对应Boolean类型的Value;
若返回了不适合的Value对象,则会抛出AssertionFailedException。
public void modify(Object element, String property, Object value);
该方法执行保存修改。一般在saveEditorValue之类的方法中调用。此处的element不再是model,而是Item类型的引用。取用对应的模型,需要使用((Item) element).getData()方法。一般此处的value值,也就是当前CellEditor的Value值,使用CellEditor.getValue()得到。另外,在执行完更改后,需要刷新对应的TableViewer或TreeViewer,使做出的更新可见。
org.eclipse.debug.internal.ui.elements.adapters.DefaultVariableCellModifier是ICellModifier的一个完整实现:
import?org.eclipse.debug.core.DebugException;
import?org.eclipse.debug.core.model.IVariable;
import?org.eclipse.debug.internal.ui.DebugUIPlugin;
import?org.eclipse.debug.internal.ui.DefaultLabelProvider;
import?org.eclipse.debug.internal.ui.VariableValueEditorManager;
import?org.eclipse.debug.ui.actions.IVariableValueEditor;
import?org.eclipse.jface.viewers.ICellModifier;
/**?*//**
?*?@since?3.2
?*
?*/
public?class?DefaultVariableCellModifier?implements?ICellModifier?{
????
????/**//*?(non-Javadoc)
?????*?@see?org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,?java.lang.String)
?????*/
????public?boolean?canModify(Object?element,?String?property)?{
????????if?(VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))?{
????????????if?(element?instanceof?IVariable)?{
????????????????return?((IVariable)?element).supportsValueModification();
????????????}
????????}
????????return?false;
????}
????/**//*?(non-Javadoc)
?????*?@see?org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,?java.lang.String)
?????*/
????public?Object?getValue(Object?element,?String?property)?{
????????if?(VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))?{
????????????if?(element?instanceof?IVariable)?{
????????????????IVariable?variable?=?(IVariable)?element;
????????????????try?{
????????????????????return?DefaultLabelProvider.escapeSpecialChars(variable.getValue().getValueString());
????????????????}?catch?(DebugException?e)?{
????????????????????DebugUIPlugin.log(e);
????????????????}
????????????}
????????}
????????return?null;
????}
????/**//*?(non-Javadoc)
?????*?@see?org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,?java.lang.String,?java.lang.Object)
?????*/
????public?void?modify(Object?element,?String?property,?Object?value)?{
????????Object?oldValue?=?getValue(element,?property);
????????if?(!value.equals(oldValue))?{
????????????if?(VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))?{
????????????????if?(element?instanceof?IVariable)?{
????????????????????IVariable?variable?=?(IVariable)?element;
????????????????????IVariableValueEditor?editor?=?VariableValueEditorManager.getDefault().getVariableValueEditor(variable.getModelIdentifier());
????????????????????if?(value?instanceof?String)?{
????????????????????????value?=?DefaultLabelProvider.encodeEsacpedChars((String)value);
????????????????????}
????????????????????if?(editor?!=?null)?{
????????????????????????if??(editor.saveVariable(variable,?(String)?value,?DebugUIPlugin.getShell()))?{
????????????????????????????return;
????????????????????????}
????????????????????}
????????????????????try?{
????????????????????????variable.setValue((String)?value);
????????????????????}?catch?(DebugException?e)?{
????????????????????????DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(),?Messages.VariableColumnPresentation_4,?Messages.VariableColumnPresentation_5,?e.getStatus());
????????????????????}
????????????????}
????????????}
????????}
????}
} 1 楼 everyday1985 2010-03-06 请教下,我按着你说的写了个CheckBoxCellEditor,想实现个功能就是如果不是根节点生成的checkBox不可用,看看CellEditor里没有可用的方法,能提供个思路不 2 楼 everyday1985 2010-03-06 everyday1985 写道请教下,我按着你说的写了个CheckBoxCellEditor,想实现个功能就是如果不是根节点生成的checkBox不可用,看看CellEditor里没有可用的方法,能提供个思路不
要是修改某个节点就可以再将其置成可用,还是在CellModifier里设置么?