`

(转)SWT的CheckBoxTreeViewer的相关用法

    博客分类:
  • SWT
 
阅读更多
最近在项目中需要用到遍历某个目录下所有文件,并按照树形结构展示,同时还需要提供对树形菜单的选择展开等操作。在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() + "\n请选择需要的文件.........................");  
  
        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);  
        }  
    }  
}  

 

分享到:
评论

相关推荐

    CheckboxTreeViewer

    直接导入就行,运行就行,java小白,model中是文件的模型,也可用io的文件和 文件夹代替

    实现坐标转换程序(C#桌面窗体)

    需手动输入坐标,实现ECEF空间直角坐标系等四种坐标之间相互转换。 具体代码流程可见主页文章。 通过下拉框,自由选择输入输出坐标系后,在左侧文本框手动输入一组或多组坐标,可以实现ECEF空间直角坐标系,ECEF球面坐标系,ECEF椭球坐标系(大地坐标系),站心坐标系四个坐标系统之间的自由转换,共12种转换方式。然后将转换后的坐标结果输入到右边文本框。 适用于GNSS相关课程的编程作业,测绘、地信等专业实践。 ------------------------------------------------------------------------------------------------------------------------- 该代码可能存在部分不足与漏洞。实际运行时没有发生过错误。

    基于matlab实现直角坐标系下的牛顿拉夫逊潮流计算MATLAB程序.rar

    基于matlab实现直角坐标系下的牛顿拉夫逊潮流计算MATLAB程序.rar

    基于matlab实现麦克风阵列SRP-PHAT算法的二级空间快速声源定位,含模拟环境 .rar

    基于matlab实现麦克风阵列SRP-PHAT算法的二级空间快速声源定位,含模拟环境。.rar

    node-v10.16.0-linux-arm64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    dephi+sqlserver2000题库与试卷生成系统.zip

    dephi+sqlserver2000题库与试卷生成系统.zip

    node-v10.24.0-darwin-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    ASP+ACCESS网页设计辅导系统(源代码+设计说明书).zip

    ASP+ACCESS网页设计辅导系统(源代码+设计说明书).zip

    中考实验视频.zip

    中考实验视频.zip

    基于VB+access实现的学生成绩管理系统(开题报告+答辩PPT+论文+系统).zip

    基于VB+access实现的学生成绩管理系统(开题报告+答辩PPT+论文+系统) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。

    基于matlab实现模拟退火程序 f(x,y) = 5sin(xy) + x^2 + y^2的最小值

    基于matlab实现模拟退火程序。f(x,y) = 5sin(xy) + x^2 + y^2的最小值,对理解模拟退火算法是一个很好的程序示例.rar

    node-v5.4.1.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    ASP+access网上人才信息管理系统毕业设计(源代码+设计说明书).zip

    ASP+access网上人才信息管理系统毕业设计(源代码+设计说明书).zip

    node-v10.22.1-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v12.16.3-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    CASS工艺参数设计计算表.xls

    污水处理计算书

    ASP+ACCESS文学网站建设设计(源代码+设计说明书+系统).zip

    ASP+ACCESS文学网站建设设计(源代码+设计说明书+系统).zip

    http代理服务器的实现(程序).zip

    http代理服务器的实现(程序).zip

    node-v6.14.4-x64.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    JSP教学管理系统设计(源代码+设计说明书).zip

    JSP教学管理系统设计(源代码+设计说明书).zip

Global site tag (gtag.js) - Google Analytics