向已有的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
protected class CustomizedTextCellEditor extends TextCellEditor {
{

 public CustomizedTextCellEditor(Composite parent)
    public CustomizedTextCellEditor(Composite parent) {
{
 super(parent);
        super(parent);
 }
    }

 protected void doSetValue(Object value)
    protected void doSetValue(Object value)  {
{
 if(value == null)
        if(value == null)
 return;
            return;
 super.doSetValue(value);
        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.DebugException;
 import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.DefaultLabelProvider;
import org.eclipse.debug.internal.ui.DefaultLabelProvider;
 import org.eclipse.debug.internal.ui.VariableValueEditorManager;
import org.eclipse.debug.internal.ui.VariableValueEditorManager;
 import org.eclipse.debug.ui.actions.IVariableValueEditor;
import org.eclipse.debug.ui.actions.IVariableValueEditor;
 import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICellModifier;


 /** *//**
/** *//**
 * @since 3.2
 * @since 3.2
 *
 *
 */
 */

 public class DefaultVariableCellModifier implements ICellModifier
public class DefaultVariableCellModifier implements ICellModifier  {
{
 
    

 /**//* (non-Javadoc)
    /**//* (non-Javadoc)
 * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
     * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
 */
     */

 public boolean canModify(Object element, String property)
    public boolean canModify(Object element, String property)  {
{

 if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))
        if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))  {
{

 if (element instanceof IVariable)
            if (element instanceof IVariable)  {
{
 return ((IVariable) element).supportsValueModification();
                return ((IVariable) element).supportsValueModification();
 }
            }
 }
        }
 return false;
        return false;
 }
    }


 /**//* (non-Javadoc)
    /**//* (non-Javadoc)
 * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
     * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
 */
     */

 public Object getValue(Object element, String property)
    public Object getValue(Object element, String property)  {
{

 if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))
        if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))  {
{

 if (element instanceof IVariable)
            if (element instanceof IVariable)  {
{
 IVariable variable = (IVariable) element;
                IVariable variable = (IVariable) element;

 try
                try  {
{
 return DefaultLabelProvider.escapeSpecialChars(variable.getValue().getValueString());
                    return DefaultLabelProvider.escapeSpecialChars(variable.getValue().getValueString());

 } catch (DebugException e)
                } catch (DebugException e)  {
{
 DebugUIPlugin.log(e);
                    DebugUIPlugin.log(e);
 }
                }
 }
            }
 }
        }
 return null;
        return null;
 }
    }


 /**//* (non-Javadoc)
    /**//* (non-Javadoc)
 * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object)
     * @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)
    public void modify(Object element, String property, Object value)  {
{
 Object oldValue = getValue(element, property);
        Object oldValue = getValue(element, property);

 if (!value.equals(oldValue))
        if (!value.equals(oldValue))  {
{

 if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))
            if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property))  {
{

 if (element instanceof IVariable)
                if (element instanceof IVariable)  {
{
 IVariable variable = (IVariable) element;
                    IVariable variable = (IVariable) element;
 IVariableValueEditor editor = VariableValueEditorManager.getDefault().getVariableValueEditor(variable.getModelIdentifier());
                    IVariableValueEditor editor = VariableValueEditorManager.getDefault().getVariableValueEditor(variable.getModelIdentifier());

 if (value instanceof String)
                    if (value instanceof String)  {
{
 value = DefaultLabelProvider.encodeEsacpedChars((String)value);
                        value = DefaultLabelProvider.encodeEsacpedChars((String)value);
 }
                    }

 if (editor != null)
                    if (editor != null)  {
{

 if  (editor.saveVariable(variable, (String) value, DebugUIPlugin.getShell()))
                        if  (editor.saveVariable(variable, (String) value, DebugUIPlugin.getShell()))  {
{
 return;
                            return;
 }
                        }
 }
                    }

 try
                    try  {
{
 variable.setValue((String) value);
                        variable.setValue((String) value);

 } catch (DebugException e)
                    } catch (DebugException e)  {
{
 DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), Messages.VariableColumnPresentation_4, Messages.VariableColumnPresentation_5, e.getStatus());
                        DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), Messages.VariableColumnPresentation_4, Messages.VariableColumnPresentation_5, e.getStatus());
 }
                    }
 }
                }
 }
            }
 }
        }
 }
    }

 }
}