[Eclipse]通过TreeColumn实现“表格树”TableTree

Eclipse 3.1里deprecate了TableTree这个控件,与之对应的jface的TableTreeViewer虽然没有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) {

        }

    }
}

下面是运行画面:

file

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2006/03/07/344853.html

给表格的单元格增加编辑功能(补充)

这一篇是对“给表格的单元格增加编辑功能”的补充,目的是让表格列显示Checkbox并允许单击改变选中状态,例子中的表格共有三列,其中后两列均需要显示为Checkbox。

步骤一,构造TableViewer;

final String[] columnNames = new String[] { "Project", "Must", "Must Not" };//columnNames在后面也要用到,所以专门定义为一个数组
TableColumn column = new TableColumn(tbv.getTable(), SWT.NONE);
column.setText(columnNames[0]);
tbv.setColumnProperties(columnNames);//给每个列指定一个字符串属性值
column.setWidth(200);
column = new TableColumn(tbv.getTable(), SWT.NONE);
column.setText(columnNames[1]);
column.setWidth(100);
column = new TableColumn(tbv.getTable(), SWT.NONE);
column.setText(columnNames[2]);
column.setWidth(100);
tbv.setContentProvider(...);
tbv.setLabelProvider(...);
tbv.setInput(...);

步骤二,定义CellEditor数组并指定给前面的TableViewer:

final CellEditor[] editors = new CellEditor[tbv.getTable().getColumnCount()];
//editors[0]保留为空,因为第一列不需要显示为Checkbox
editors[1] = new CheckboxCellEditor(tbv.getTable());
editors[2] = new CheckboxCellEditor(tbv.getTable());
tbv.setCellEditors(editors);

步骤三,定义TableViewer的CellModifier,作用是告诉表格如何改变对象的属性值,注意在modify()方法里参数element可能是org.eclipse.swt.widgets.Item类型,如果是这种情况要通过Item#getData()得到实际的对象:

tbv.setCellModifier(new ICellModifier() {
    public boolean canModify(Object element, String property) {
        return property.equals(columnNames[1]) || property.equals(columnNames[2]);
    }

    public Object getValue(Object element, String property) {
        PortfolioItem item = (PortfolioItem) element;
        if (property.equals(columnNames[1])) {
            return Boolean.valueOf(item.isMust());
        }
        if (property.equals(columnNames[2])) {
            return Boolean.valueOf(item.isMustNot());
        }
        return null;
    }

    public void modify(Object element, String property, Object value) {
        if (element instanceof Item)
            element = ((Item) element).getData();
        PortfolioItem item = (PortfolioItem) element;
        if (property.equals(columnNames[1])) {
            item.setMust(((Boolean) value).booleanValue());
        }
        if (property.equals(columnNames[2])) {
            item.setMustNot(((Boolean) value).booleanValue());
        }
    }
});

步骤四,这时单击表格可以改变选中状态了,但显示的是True/False(或其他在LableProvider里定义的内容),见图1,而非Checkbox控件选中/清空的样子。

file
图1 单击表格单元可改变T/F

解决的办法很简单,在LabelProvider里根据属性值True/False显示不同的图片即可,这两个图片可以在这里下载(鼠标右键另存为):

public Object getColumnImage(Object object, int columnIndex) {
    PortfolioItem item=(PortfolioItem)object;
    switch (columnIndex) {
    case 1:
        return item.isMust()?PortfolioEditPlugin.getPlugin().getImage("checked"):PortfolioEditPlugin.getPlugin().getImage("unchecked");
    case 2:
        return item.isMustNot()?PortfolioEditPlugin.getPlugin().getImage("checked"):PortfolioEditPlugin.getPlugin().getImage("unchecked");
    default:
        return null;
    }        
}

public String getColumnText(Object object, int columnIndex) {
    PortfolioItem item=(PortfolioItem)object;
    switch (columnIndex) {
    case 0:
        return item.getProject()==null?"N/A":item.getProject().getName();
//在显示为Checkbox的两列里不需要文字
//        case 1:
//            return item.isMust()?"True":"False";
//        case 2:
//            return item.isMustNot()?"True":"False";
    default:
        return "";
    }
}

最后是运行结果:

file

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2006/02/25/337367.html

[Eclipse]处理颜色类型的偏好项

在Eclipse里实现偏好页(PreferencePages)时,我们一般要在Plugin类的start()方法里预先设置好每一项的缺省值,但IPreferenceStore接口只提供了参数为整型、布尔型、字符串等基本类型的setDefault()方法,如果某个偏好项是颜色类型怎么办呢?

这时要使用PreferenceConverter这个类,也是由jface提供的,该类提供了额外的一些setDefault()方法可以接收RGB、Font、Point等类型的参数,所以可以使用下面的方法设置缺省值:

PreferenceConverter.setDefault(getPreferenceStore(), IConstants.PREF_COLOR_PRIORITY_HIGH, new RGB(255, 128, 64));

要取得某个颜色类型的偏好项值,就用下面的语句:

PreferenceConverter.getColor(CbmPlugin.getDefault().getPreferenceStore(), IConstants.PREF_COLOR_PRIORITY_HIGH)

JFace在颜色、图象和字体等资源的管理方面为我们做了很多工作,我们应该尽量利用已有的这些功能。

file
图1 颜色类型的偏好项

顺便说一下,要让editor里的图形在用户更改preference设置后立即反应变化,要在preferenceStore上增加监听器,例如在editor的initializeGraphicalViewer()方法里这样写:

protected void initializeGraphicalViewer() {

    Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
            // You may refresh some editparts only for better performance
            //    if(IConstants.PREF_SHOW_ACTIVITIES.equals(event.getProperty()))
                refreshAllEditParts(getGraphicalViewer().getRootEditPart());
        }

        private void refreshAllEditParts(EditPart part) {
            part.refresh();
            List children = part.getChildren();
            for (Iterator iter = children.iterator(); iter.hasNext();) {
                EditPart child = (EditPart) iter.next();
                refreshAllEditParts(child);
            }
        }

    });
}

最后,org.eclipse.ui.preferencePages扩展点的page元素的category属性的值应该是另一个page的id值。

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2005/04/12/136105.html