zoukankan      html  css  js  c++  java
  • (转)SWT的CheckBoxTreeViewer的相关用法

    最近在项目中需要用到遍历某个目录下所有文件,并按照树形结构展示,同时还需要提供对树形菜单的选择展开等操作。在eclipse中提供了CheckboxTreeViewer组件来满足所需要的功能
    下面是需要实现的功能:
    按照树形菜单列出指定目录下文件列表
    对菜单操作的相应处理,如选中父级菜单子集选中等
    选中的菜单内容保存,并再次打开中默认选中
     
    1、使用TitleAreaDialog创建 
    TitleAreaDialog是Eclipse的Jface组件中的一个对话框,提供了显示的标题、提示信息和图标以及和内容区域,以及两个默认的按钮。我们在eclipse中常见的New Java Class Wizard就是一个典型的界面。
    在自定义的界面中需要继承TitleAreaDialog
    Java代码  
    public class FrameworkFilterDialog extends TitleAreaDialog  
     绘制具体界面内容:实现createDialogArea
    Java代码  
    @Override  
        protected Control createDialogArea(Composite parent) {  
            Composite area = (Composite) super.createDialogArea(parent);  
            Composite container = new Composite(area, SWT.NONE);  
            container.setLayoutData(new GridData(GridData.FILL_BOTH));  
            //设置消息标题、消息信息  
            setTitle("Configuration ...........");  
            setMessage("配置该工程下的文件..........");  
      
            //主体内容部分,这里做一些必要描述  
            Label lblNewLabel = new Label(container, SWT.NONE);  
            lblNewLabel.setBounds(0, 0, 658, 39);  
            lblNewLabel.setText("工程名:  " + project.getName() + "
    请选择需要的文件.........................");  
      
            IPath path = project.getRawLocation();  
      
            //这里绑定CheckboxTreeViewer 的相关属性和事件监听  
            CheckboxTreeViewer checkboxTreeViewer = new CheckboxTreeViewer(container, SWT.BORDER);  
            checkboxTreeViewer.setContentProvider(new FrameworkConfigContentProvider());  
            checkboxTreeViewer.setLabelProvider(new FrameworkConfigLabelProvider());  
            checkboxTreeViewer.addCheckStateListener(new FrameworkCheckedListener(path.toOSString()));  
            checkboxTreeViewer.setInput(ProjectFileDirUtil.listProjectFileDirec(path.toString()));  
      
            Tree tree = checkboxTreeViewer.getTree();  
            tree.setBounds(0, 45, 658, 229);  
            List<String> checkedList = FrameFilterManager.getManager().getFrameworkFilterFiles(project.getName());  
      
            //bind tree expand event: initialize tree checked  
            tree.addListener(SWT.Expand, new FrameworkExpandListener(checkedList));  
      
            //set initialize checked: first level tree checked  
            if (!LogicUtil.isEmpty(checkedList)) {  
                File[] file = ProjectFileDirUtil.changePathToFiles(checkedList);  
                checkboxTreeViewer.setCheckedElements(file);  
            }  
      
            return area;  
        }  
     运行的效果如下:
    
     
    2、这里对CheckboxTreeViewer的几个属性设置做进一步说明
    Java代码  
    checkboxTreeViewer.setContentProvider(new FrameworkConfigContentProvider());  
    checkboxTreeViewer.setLabelProvider(new FrameworkConfigLabelProvider());  
     根据方法名很容易知道,是对该树形结构提供数据和展现哪些数据。需要分别实现接口ITreeContentProvider:提供了获取下级元素和获取元素的方法。这里是一个简单的例子:
    Java代码  
    public class FrameworkConfigContentProvider implements ITreeContentProvider {  
      
        @Override  
        public void dispose() {  
      
        }  
      
        @Override  
        public void inputChanged(Viewer arg0, Object arg1, Object arg2) {  
      
        }  
      
        @Override  
        public Object[] getChildren(Object parentElement) {  
            if (parentElement instanceof File) {  
                File file = (File) parentElement;  
                File[] list = file.listFiles(new ProjectDirFileFilter());  
                if (list == null || list.length <= 0) {  
                    return new Object[0];  
                }  
                return list;  
            }  
            return new Object[0];  
        }  
      
        @Override  
        public Object[] getElements(Object inputElement) {  
            if (inputElement instanceof File[]) {  
                File[] fileList = (File[]) inputElement;  
                if (fileList == null || fileList.length <= 0) {  
                    return new Object[0];  
                }  
                return fileList;  
            }  
            return new Object[0];  
        }  
      
        @Override  
        public Object getParent(Object arg0) {  
            return null;  
        }  
      
        @Override  
        public boolean hasChildren(Object inputElement) {  
            if (inputElement instanceof File) {  
                File file = (File) inputElement;  
                File[] list = file.listFiles(new ProjectDirFileFilter());  
                if (list == null || list.length <= 0) {  
                    return false;  
                }  
                return true;  
            }  
            return false;  
        }  
    }  
     
    同样对LabelProvider主要用于绘制菜单是显示的内容,如图标、标题等
    Java代码  
    public class FrameworkConfigLabelProvider extends LabelProvider {  
      
        private static final String PACKAGE           = "src";  
        private static final String JAVA_FILE         = ".java";  
        private static final String XML_FILE          = ".xml";  
        private static final String PROP_FILE         = ".properties";  
      
        private Image               javaFile          = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_JAVA_OBJ));  
      
        private Image               file              = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_FILE_OBJ));  
      
        private Image               xmlFile           = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_XML_OBJ));  
      
        private Image               folderFile        = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_FILEFOLDER_OBJ));  
      
        private Image               packageFolderFile = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_PACKAGE_FOLDER));  
      
        private Image               propFile          = new Image(Display.getCurrent(), getClass().getResourceAsStream(  
                                                              CommonConstants.ICON_PROP_OBJ));  
      
        @Override  
        public Image getImage(Object element) {  
      
            if (element instanceof File) {  
                File file = (File) element;  
                String fileName = file.getName();  
                //source folder  
                if (fileName.equals(PACKAGE)) {  
                    return packageFolderFile;  
                }  
                //folder  
                if (file.isDirectory()) {  
                    return folderFile;  
                }  
                //judge by suffix  
                if (fileName.indexOf(JAVA_FILE) > 0) {  
                    return javaFile;  
                } else if (fileName.indexOf(XML_FILE) > 0) {  
                    return xmlFile;  
                } else if (fileName.indexOf(PROP_FILE) > 0) {  
                    return propFile;  
                }  
            }  
            return file;  
        }  
      
        @Override  
        public String getText(Object element) {  
            File file = (File) element;  
            return file.getName();  
        }  
      
        @Override  
        public void dispose() {  
            javaFile.dispose();  
            packageFolderFile.dispose();  
            folderFile.dispose();  
            xmlFile.dispose();  
            propFile.dispose();  
            file.dispose();  
            super.dispose();  
        }  
      
    }  
     
    3、设置选中事件
    包括两种:选中上级目录时子集目录全部选中、如果下级目录不是全部选中上级菜单也不能选中等
    在CheckboxTreeViewer中提供了addCheckStateListener对选择事件的监听,这里需要实现上面说的功能:
    Java代码  
    checkboxTreeViewer.addCheckStateListener(new FrameworkCheckedListener(path.toOSString()));  
    FrameworkCheckedListener需要实现接口ICheckStateListener
    Java代码  
    @Override  
    public void checkStateChanged(CheckStateChangedEvent event) {  
        if (event.getChecked()) {  
            CheckboxTreeViewer viewer = (CheckboxTreeViewer) event.getSource();  
            //选中:设置下级菜单选中  
            viewer.setSubtreeChecked(event.getElement(), true);  
            //选中:如果是子集菜单,且同级菜单全是选中的时候设置parent选中  
            //同样如果此时parent所在的同级菜单全选中做相应的迭代处理  
            //TODO:获取所有选中的项,比较绝对路径  
      
        } else {  
            CheckboxTreeViewer viewer = (CheckboxTreeViewer) event.getSource();  
            //不选中:下级目录菜单全不选中  
            File file = (File) event.getElement();  
            viewer.setSubtreeChecked(file, false);  
            //不选中:如果父级菜单是选中不能设置为选中  
            File parent = file.getParentFile();  
            //这里需要注意如果是顶级菜单不再迭代设置,否则将会空指针  
            if (parent.exists() && !parent.getAbsolutePath().equals(projectRoot)) {  
                setParentUnchecked(viewer, file.getParentFile());  
            }  
        }  
      
    }  
     
    4、菜单选中内容保存和初始化默认选中 
    对选择菜单的保存,采用这种方式提供了相应的事件监听okPressed:
    Java代码  
    /** 
     * 设置OK点击事件后相应处理 
     */  
    @Override  
    protected void okPressed() {  
        Object[] dirFiles = checkboxTreeViewer.getCheckedElements();  
        List<String> dataList = new ArrayList<String>();  
        for (Object obj : dirFiles) {  
            if (obj instanceof File) {  
                File file = (File) obj;  
                dataList.add(file.getAbsolutePath());  
            }  
        }  
        //将选中的结果保存  
        FrameFilterManager.getManager().saveFrameworkFilterFiles(project.getName(), dataList);  
        super.okPressed();  
    }  
     对初始化选中是让人很纠结的一件事,在CheckboxTreeViewer中提供了setCheckedElements(Objects[ ] args)但是在实践中发现只会对一级菜单的项进行匹配选中,对二级或更多就无能为力了,不知道是我操作不正确还是怎么回事。
    Java代码  
    //set initialize checked: first level tree checked  
    if (!LogicUtil.isEmpty(checkedList)) {  
        File[] file = ProjectFileDirUtil.changePathToFiles(checkedList);  
        checkboxTreeViewer.setCheckedElements(file);  
    }  
     这里设置的对象需要和setInput中的数据类型保持一致。但是这里是会选中,也仅限于一级菜单。为了达到目的,这里对CheckboxTreeViewer中的Tree添加expand事件来实现
    Java代码  
    Tree tree = checkboxTreeViewer.getTree();  
    tree.setBounds(0, 45, 658, 229);  
    List<String> checkedList = FrameFilterManager.getManager().getFrameworkFilterFiles(project.getName());  
      
    //bind tree expand event: initialize tree checked  
    tree.addListener(SWT.Expand, new FrameworkExpandListener(checkedList));  
     这里FrameworkExpandListener需要实现SWT中的Listener接口,并根据特别的情况来设置相应的选中
    Java代码  
    @Override  
    public void handleEvent(Event event) {  
      
        if (LogicUtil.isEmpty(checkedList)) {  
            checkedList = new ArrayList<String>();  
        }  
      
        //当前点击item  
        TreeItem item = (TreeItem) event.item;  
        TreeItem[] items = item.getItems();  
      
        for (TreeItem treeItem : items) {  
            File file = (File) treeItem.getData();  
            if (checkedList.contains(file.getAbsolutePath())) {  
                treeItem.setChecked(true);  
            }  
        }  
    }  
  • 相关阅读:
    python中的time模块
    CSS 布局
    8 Function类型
    2 node 核心
    1 node 简介
    13 对象
    JS 算法一
    JS 模块化
    1 谈谈section标签
    JS 练习一
  • 原文地址:https://www.cnblogs.com/wangjiyuan/p/zhuan1.html
Copyright © 2011-2022 走看看