向已有的TreeViewer和TableViewer上添加編輯功能,可以使用CellEditor和CellModifier。
CellEditor定義了某個列被編輯時顯示的外觀,它可以是文本框、下拉列表框或單選框,也可以自己定義。
通常使用的CellEditor的子類就是:CheckboxCellEditor、ComboBoxCellEditor和TextCellEditor。
CellEditor一般用數(shù)組來保存,如果某個列不需要編輯,則可將該列的CellEditor設(shè)為null。
當(dāng)CellEditor的數(shù)組定義完后,即可利用setCellEditors(CellEditor[] editors)方法將該數(shù)組設(shè)置到對應(yīng)的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,避免了設(shè)置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負(fù)責(zé)外觀,它對要編輯的模型信息一無所知。所以jface中引入了ICellModifier接口,將model與CellEditor聯(lián)系在一起。為了確定在CellModifier中的列,需要定義columnProperties的String[]數(shù)組,用以區(qū)分不同列對應(yīng)的不同屬性。使用setColumnProperties(String[] columnProperties)設(shè)置該屬性集。
ICellModifier定義了三個接口方法:
public boolean canModify(Object element, String property);
該方法判斷何時該列可以被編輯。其中element是對應(yīng)的model。返回true表示此時該列可以被編輯。
public Object getValue(Object element, String property);
該方法一般在activateCellEditor()時調(diào)用,用于設(shè)定CellEditor的初始值。其中element是對應(yīng)的model。
此處雖然可以返回Object類型的引用,但是使用時需小心,特定的CellEditor僅接受特定類型的Value。比如:
TextCellEditor對應(yīng)String類型的Value;
ComboBoxCellEditor對應(yīng)Integer類型的Value;
CheckBoxCellEditor對應(yīng)Boolean類型的Value;
若返回了不適合的Value對象,則會拋出AssertionFailedException。
public void modify(Object element, String property, Object value);
該方法執(zhí)行保存修改。一般在saveEditorValue之類的方法中調(diào)用。此處的element不再是model,而是Item類型的引用。取用對應(yīng)的模型,需要使用((Item) element).getData()方法。一般此處的value值,也就是當(dāng)前CellEditor的Value值,使用CellEditor.getValue()得到。另外,在執(zhí)行完更改后,需要刷新對應(yīng)的TableViewer或TreeViewer,使做出的更新可見。
org.eclipse.debug.internal.ui.elements.adapters.DefaultVariableCellModifier是ICellModifier的一個完整實(shí)現(xiàn):
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());
????????????????????}
????????????????}
????????????}
????????}
????}

}