SWT TableTree

SWT TableTree
 

通过TreeColumn实现表格树”TableTree

Eclipse 3.1deprecateTableTree这个控件,与之对应的jfaceTableTreeViewer虽然没有deprecate,但使用它会得到很多警告。在TableTreeViewer的第一列里是不能显示图标的,因为这个位置被+/-符号占用了,而且TableTree是显示不出 Tree的层次的,也就是没有缩进。

SWT 3.1里的Tree控件新支持了列的显示,是通过TreeColumn来实现的。在jface里则没有添加新的viewer,使用原先的TreeViewer即可支持,下面是一段例子代码,注意如果在windows里运行要修改一下setInput()这条语句的参数,例如改为setInput(new File("c:"""))

import java.io.File;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeColumn;


public class TreeColumnTest {
    
    
public void run(){
        
final Display display = new Display();
        
final Shell shell = new Shell(display);
        shell.setLayout(
new FillLayout());
        
        
final TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION);
        viewer.getTree().setHeaderVisible(
true);
        TreeColumn column = 
new TreeColumn(viewer.getTree(), SWT.LEFT);
        column.setText("Name");
        column.setWidth(200);
        column = 
new TreeColumn(viewer.getTree(), SWT.LEFT);
        column.setText("Size");
        column.setWidth(100);
        column = 
new TreeColumn(viewer.getTree(), SWT.LEFT);
        column.setText("Hidden");
        column.setWidth(100);
        viewer.setContentProvider(
new MyTreeContenetProvider());
        viewer.setLabelProvider(
new MyTableLableProvider());
        viewer.setInput(
new File("/"));

        shell.open();
        
while (!shell.isDisposed()) {
            
if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    
public static void main(String[] args) {
        
new TreeColumnTest().run();
    }
    
    
class MyTreeContenetProvider implements ITreeContentProvider{

        
public Object[] getChildren(Object parentElement) {
            File file=(File)parentElement;
            
if(file.isDirectory())
                
return file.listFiles();
            
else
                
return null;
        }

        
public Object getParent(Object element) {
            File file=(File)element;
            
return file.getParentFile();
        }

        
public boolean hasChildren(Object element) {
            File file=(File)element;
            
return file.isDirectory()/*&&file.list().length>0*/;
        }

        
public Object[] getElements(Object inputElement) {
            File file=(File)inputElement;
            
return file.isDirectory()?file.listFiles():new Object[]{file};
        }

        
public void dispose() {
            
        }

        
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            
        }
        
    }
    
    
class MyTableLableProvider implements ITableLabelProvider{

        
public Image getColumnImage(Object element, int columnIndex) {
            
return null;
        }

        
public String getColumnText(Object element, int columnIndex) {
            File file=(File)element;
            
switch (columnIndex) {
            
case 0:
                
return file.getName();
            
case 1:
                
return ""+file.length();
            
case 2:
                
return ""+file.isHidden();
            
default:
                
return "";
            }
        }

        
public void addListener(ILabelProviderListener listener) {
            
        }

        
public void dispose() {
            
        }

        
public boolean isLabelProperty(Object element, String property) {
            
return false;
        }

        
public void removeListener(ILabelProviderListener listener) {
            
        }
        
    }
}

这是运行画面:

向已有的TreeViewerTableViewer上添加编辑功能,可以使用CellEditorCellModifier

CellEditor定义了某个列被编辑时显示的外观,它可以是文本框、下拉列表框或单选框,也可以自己定义。

通常使用的CellEditor的子类就是:CheckboxCellEditorComboBoxCellEditorTextCellEditor
CellEditor
一般用数组来保存,如果某个列不需要编辑,则可将该列的CellEditor设为null
CellEditor的数组定义完后,即可利用setCellEditors(CellEditor[] editors)方法将该数组设置到对应的TreeViewerTableViewer中去。例如:

    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接口,将modelCellEditor联系在一起。为了确定在CellModifier中的列,需要定义columnPropertiesString[]数组,用以区分不同列对应的不同属性。使用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值,也就是当前CellEditorValue值,使用CellEditor.getValue()得到。另外,在执行完更改后,需要刷新对应的TableViewerTreeViewer,使做出的更新可见。

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());
                    }
                }
            }
        }
    }

}

你可能感兴趣的:(SWT TableTree)