zoukankan      html  css  js  c++  java
  • 自定义SWT控件五之自定义穿梭框

    5、自定义穿梭框

    package com.view.control.shuttlebox;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.custom.CLabel;
    import org.eclipse.swt.custom.ScrolledComposite;
    import org.eclipse.swt.custom.StyledText;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Control;
    import org.eclipse.swt.widgets.Event;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.Listener;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.global.constant.Constants;
    import com.util.CollectionUtil;
    import com.util.FileUtil;
    import com.util.StringUtil;
    import com.view.control.DefinedSearchText.SearchTextEvent;
    import com.view.control.DefinedSearchText;
    import com.view.control.select.SearchDropDown;
    import com.view.swt.CustomMessageBox;
    import com.view.swt.SWTResourceManager;
    import com.view.swt.SWTUtil;
    import com.view.swt.StyleTextLink;
    import com.view.swt.CustomMessageBox.Model;
    import com.view.util.ImageUtil;
    
    public abstract class DefinedCommonSearchShuttleBox<T> extends SearchDropDown<T> {
        private static final Logger log = LoggerFactory.getLogger(DefinedCommonSearchShuttleBox.class);
        /***数字区域*****/
        protected CLabel num_label ;
        protected CLabel right_num_label;
        protected Composite rightScrolledContentComposite;
        protected StyleTextLink.StyleTextLinkEvent linkEvent;
        protected String noContentMention = "您可以更新获取选型数据后再进行查询";
        protected String linkText = "更新";
        protected SearchShuttleBoxEvent<T> searchShuttleBoxEvent;
        /***在左侧区域已选择的条目***/
        protected List<T> selectedList = new ArrayList<>();
        protected Map<T,Composite> selectMap = new HashMap<T,Composite>();
        /*****右侧区域选中的内容*******/
        protected Map<T,Composite> rightSelectMap = new HashMap<T,Composite>(); 
        /*****右侧区域所有数据****/
        protected List<T> rightDataList = new ArrayList<>();
        @Deprecated
        public DefinedCommonSearchShuttleBox(Composite parent, List<T> comboDataList, int comboRowWidth,
                SearchTextEvent<T> searchTextEvent) {
            super(parent, comboDataList, comboRowWidth, searchTextEvent);
        }
    
        public DefinedCommonSearchShuttleBox(Composite parent,DefinedSearchText.SearchTextEvent<T> searchTextEvent,int comboRowWidth){
            super(parent, searchTextEvent, comboRowWidth);
        }
        
        @Override
        public void paint() {
            Composite content_composite = new Composite(this.parent,SWT.NONE);
            GridData gd_content_composite = new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
            content_composite.setLayoutData(gd_content_composite);
            GridLayout gl_content_composite = new GridLayout(3,false);
            gl_content_composite.marginWidth = 0;
            gl_content_composite.marginHeight = 0;
            gl_content_composite.horizontalSpacing = 5;
            gl_content_composite.verticalSpacing = 0;
            content_composite.setLayout(gl_content_composite);
            content_composite.setBackground(SWTResourceManager.getWhiteColor());
            //绘制左侧区域
            generateLeftComposite(content_composite);
            //绘制中间区域
            generateMiddleComposite(content_composite);
            //绘制右侧区域
            generateRightComposite(content_composite);
            if(!this.initEmpty){
                super.notifySearch();
            }
        }
        
        /**
         * 绘制左侧区域内容
         * @author wangfang5 2018年5月23日 上午11:04:28
         * @param content_composite
         */
        private void generateLeftComposite(Composite content_composite) {
            Composite left_content_composite = new Composite(content_composite, SWT.NONE);
            GridData gd_left_content_composite = new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1);
            left_content_composite.setLayoutData(gd_left_content_composite);
            GridLayout gl_left_content_composite = new GridLayout(1, true);
            gl_left_content_composite.marginHeight = 5;
            gl_left_content_composite.marginWidth = 5;
            gl_left_content_composite.verticalSpacing = 5;
            gl_left_content_composite.horizontalSpacing = 0;
            left_content_composite.setLayout(gl_left_content_composite);
            SWTUtil.paintBorder(left_content_composite, SWTResourceManager.getBorderColor());
            left_content_composite.setBackground(SWTResourceManager.getWhiteColor());
            
            // 绘制可选数字
            Composite title_composite = new Composite(left_content_composite, SWT.NONE);
            title_composite.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_title_composite = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
            title_composite.setLayoutData(gd_title_composite);
            GridLayout gl_title_composite = new GridLayout(2, false);
            gl_title_composite.verticalSpacing = 0;
            gl_title_composite.horizontalSpacing = 5;
            gl_title_composite.marginHeight = 0;
            gl_title_composite.marginWidth = 0;
            title_composite.setLayout(gl_title_composite);
            CLabel title_label = new CLabel(title_composite, SWT.NONE);
            title_label.setText("可选");
            title_label.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_title_label = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
            title_label.setLayoutData(gd_title_label);
            num_label = new CLabel(title_composite, SWT.NONE);
            num_label.setText("(当前选中0/0)");
            num_label.setBackground(SWTResourceManager.getWhiteColor());
            num_label.setForeground(SWTResourceManager.getTextColor());
            GridData gd_num_label = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
            num_label.setLayoutData(gd_num_label);
            
            searchTextEvent = new DefinedSearchText.SearchTextEvent<T>(){
                @Override
                public DefinedSearchText.SearchPageResult<T> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters) {
                   if(null != searchShuttleBoxEvent){
                       return searchShuttleBoxEvent.search(event, searchKeys, pageNum, pagePerNum, filters);
                   }else{
                       log.error(toLog("", "no searchTextEvent"));
                       return null;
                   }
                }
    
                @Override
                public boolean beforeEvent(Event event,String searchKey) {
                    if(null != searchShuttleBoxEvent){
                        String verifyMsg = searchShuttleBoxEvent.verifySearchContent(searchKey);
                        if(StringUtil.isNotNullAndEmpty(verifyMsg)){ //校验不通过
                            showErrorMention(verifyMsg);
                            return false;
                        }else{   //校验通过
                            showNormalMention();
                        }
                    }
                    externalBeforeEvent(event);
                    beforeSearchClick(event);
                    return true;
                }
    
                @Override
                public void afterEvent(Event event, List<T> dataList) {
                    afterSearchClick(event,dataList);
                }
            };
            generateSearchCompoiste(left_content_composite);
        }
        /**
         * 搜索之前需要做的事情,将右侧中的数据作为筛选条件传递到搜索条件中
         * @param event
         */
        protected void externalBeforeEvent(Event event){
            if(event.button == 1){  //event.button == 1 表示点击搜索按钮
                selectedList.clear();
                selectMap.clear();
                replaceSearchExternalFilter(new ArrayList<>(rightDataList),0);
            }
        }
        
        /**
         * 绘制中间的区域
         * @param content_composite
         */
        private void generateMiddleComposite(Composite content_composite){
            Composite middle_composite = new Composite(content_composite,SWT.NONE);
            middle_composite.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_middle_composite = new GridData(SWT.FILL,SWT.CENTER,false,true,1,1);
            gd_middle_composite.widthHint = 50;
            middle_composite.setLayoutData(gd_middle_composite);
            GridLayout gl_middle_composite = new GridLayout(1,true);
            gl_middle_composite.verticalSpacing = 10;
            gl_middle_composite.marginHeight = 0;
            gl_middle_composite.marginWidth = 0;
            gl_middle_composite.horizontalSpacing = 0;
            middle_composite.setLayout(gl_middle_composite);
            
            //放置向右移动图标
            Label right_label = new Label(middle_composite,SWT.NONE);
            GridData gd_right_label = new GridData(SWT.CENTER,SWT.CENTER,false,false,1,1);
            gd_right_label.widthHint = 48;
            gd_right_label.heightHint = 32;
            right_label.setLayoutData(gd_right_label);
            right_label.setBackground(SWTResourceManager.getWhiteColor());
            right_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.SHUTTLE_RIGHT_IMG)));
            right_label.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            right_label.addListener(SWT.MouseDown, new Listener(){
                @Override
                public void handleEvent(Event event) {
                    rightMoveEvent(event);
                }
            });
            
            //放置向左图标
            Label left_label = new Label(middle_composite,SWT.NONE);
            GridData gd_left_label= new GridData(SWT.CENTER,SWT.CENTER,true,false,1,1);
            gd_left_label.widthHint = 48;
            gd_left_label.heightHint = 32;
            left_label.setLayoutData(gd_left_label);
            left_label.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            left_label.setBackground(SWTResourceManager.getWhiteColor());
            left_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.SHUTTLE_LEFT_IMG)));
            left_label.addListener(SWT.MouseDown, new Listener(){
                @Override
                public void handleEvent(Event event) {
                    leftMoveEvent(event);
                }
            });
        }
        
        /**
         * 向右移动触发的事件(绘制界面)
         * @param event
         */
        protected void rightMoveEvent(Event event){
            if(CollectionUtil.isEmpty(selectedList)){
                new CustomMessageBox(this.parent.getShell(), "请在左侧区域选择移动项!", Model.CONFIRM_MODEL).open();
                return;
            }
            boolean allowable = false;
            if(null == searchShuttleBoxEvent){
                allowable = true;
            }else if(searchShuttleBoxEvent.addEvent(selectedList,this)){
                allowable = true;
            }else{
                new CustomMessageBox(this.parent.getShell(), "向右测移动失败!", Model.CONFIRM_MODEL).open();
                return;
            }
            if(allowable){
                for(Entry<T, Composite> entry:selectMap.entrySet()){
                    entry.getValue().dispose();
                    //右侧绘制一个内容
                    generateRightItem(entry.getKey());
                    rightDataList.add(entry.getKey());
                    this.totalCount--;
                }
                selectedList.clear();
                selectMap.clear();
                updateRightNum();
                updateLeftNum();
                notifyScrollSearch();
                relayoutScrollComposite();
                relayoutRightScrollComposite();
            }
        }
        
        /**
         * 绘制右侧的区域
         * @param content_composite
         */
        private void generateRightComposite(Composite content_composite){
            Composite right_content_composite = new Composite(content_composite, SWT.NONE);
            GridData gd_right_content_composite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
            right_content_composite.setLayoutData(gd_right_content_composite);
            GridLayout gl_right_content_composite = new GridLayout(1, true);
            gl_right_content_composite.marginHeight = 5;
            gl_right_content_composite.marginWidth = 5;
            gl_right_content_composite.verticalSpacing = 5;
            gl_right_content_composite.horizontalSpacing = 0;
            right_content_composite.setLayout(gl_right_content_composite);
            SWTUtil.paintBorder(right_content_composite, SWTResourceManager.getBorderColor());
            right_content_composite.setBackground(SWTResourceManager.getWhiteColor());
            
            // 绘制可选数字
            Composite title_composite = new Composite(right_content_composite, SWT.NONE);
            title_composite.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_title_composite = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
            title_composite.setLayoutData(gd_title_composite);
            GridLayout gl_title_composite = new GridLayout(2, false);
            gl_title_composite.verticalSpacing = 0;
            gl_title_composite.horizontalSpacing = 5;
            gl_title_composite.marginHeight = 0;
            gl_title_composite.marginWidth = 0;
            title_composite.setLayout(gl_title_composite);
            CLabel title_label = new CLabel(title_composite, SWT.NONE);
            title_label.setText("已选");
            title_label.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_title_label = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
            title_label.setLayoutData(gd_title_label);
            right_num_label = new CLabel(title_composite, SWT.NONE);
            right_num_label.setText("(0)");
            right_num_label.setBackground(SWTResourceManager.getWhiteColor());
            right_num_label.setForeground(SWTResourceManager.getTextColor());
            GridData gd_right_num_label = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
            right_num_label.setLayoutData(gd_right_num_label);
            generateRightListComposite(right_content_composite);
        }
        
        /**
         * 绘制右侧区域内容
         * @param right_composite
         */
        private void generateRightListComposite(Composite right_composite){
            ScrolledComposite rightScrolledComposite = new ScrolledComposite(right_composite, SWT.V_SCROLL);
            rightScrolledComposite.setExpandHorizontal(true);
            rightScrolledComposite.setExpandVertical(true);
            rightScrolledComposite.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_rightScrolledComposite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
            rightScrolledComposite.setLayoutData(gd_rightScrolledComposite);
            
            rightScrolledContentComposite = new Composite(rightScrolledComposite,SWT.NONE);
            rightScrolledComposite.setContent(rightScrolledContentComposite);
            rightScrolledContentComposite.setBackground(SWTResourceManager.getWhiteColor());
            GridLayout gl_rightScrolledContentComposite = new GridLayout(1, true);
            gl_rightScrolledContentComposite.marginWidth = 10;
            gl_rightScrolledContentComposite.marginHeight = 0;
            gl_rightScrolledContentComposite.verticalSpacing = 0;
            gl_rightScrolledContentComposite.horizontalSpacing = 0;
            rightScrolledContentComposite.setLayout(gl_rightScrolledContentComposite);
        }
        @Override
        protected void generateNoContentMentionComposite(Composite searchContentComposite, String searchContent,int width) {
            StyledText styledText = new StyledText(searchContentComposite,SWT.WRAP|SWT.MULTI);
            styledText.setText(StringUtil.isNotNullAndEmpty(searchContent)?"未找到与"+searchContent+"相关的内容,"+noContentMention:"暂无数据,"+noContentMention);
            GridData gd_styledText = new GridData(SWT.CENTER,SWT.CENTER,false,true,1,1);
            gd_styledText.widthHint = width;
            styledText.setLayoutData(gd_styledText);
            styledText.setEditable(false);
            StyleTextLink link = new StyleTextLink(linkEvent,styledText);
            link.ReplaceLink(linkText);
            searchContentComposite.layout(true);
        }
        
        @Override
        protected void generateComboContent(boolean append,List<T> dataList){
            Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
            if(null == this.comboDataList){
                this.comboDataList = new ArrayList<>();
            }
            if(!append){
                for(Control control:searchContentComposite.getChildren()){
                    control.dispose();
                }
                this.comboDataList.clear();
                searchScrollContentComposite.setMinSize(0, 0);
            }
            if (CollectionUtil.isNotEmpty(dataList)) {
                for (T data : dataList) {
                    generateComboItem(data);
                }
                this.comboDataList.addAll(dataList);
                if(append){
                    CLabel loadLabel = (CLabel)searchScrollContentComposite.getData("load");
                    GridData gd_loadLabel = (GridData)loadLabel.getLayoutData();
                    gd_loadLabel.exclude = true;
                    loadLabel.setVisible(false);
                }
                updateLeftNum();
            }else if(!append){   //形成待更新内容
                generateNoContentMentionComposite(searchContentComposite,this.getFilterContent(),this.comboRowWidth-30);
                updateLeftNum();
            }else{  //异步加载数据的情况
                if(CollectionUtil.isEmpty(this.comboDataList)){
                    updateLeftNum();
                    generateNoContentMentionComposite(searchContentComposite,this.getFilterContent(),this.comboRowWidth-30);
                    CLabel loadLabel = (CLabel)searchScrollContentComposite.getData("load");
                    GridData gd_loadLabel = (GridData)loadLabel.getLayoutData();
                    gd_loadLabel.exclude = true;
                    loadLabel.setVisible(false);
                    finish = true;
                }else if(CollectionUtil.isEmpty(dataList)){
                    CLabel loadLabel = (CLabel)searchScrollContentComposite.getData("load");
                    GridData gd_loadLabel = (GridData)loadLabel.getLayoutData();
                    gd_loadLabel.exclude = false;
                    loadLabel.setText("无更多数据");
                    loadLabel.setVisible(true);
                    finish = true;
                }
            }
            relayoutScrollComposite();
        }
        
        abstract void generateRightItem(T data);
        
        /**
         * 向左移动触发的事件(绘制界面)
         * @param event
         */
        protected void leftMoveEvent(Event event){
            if(CollectionUtil.isEmpty(rightSelectMap)){
                 new CustomMessageBox(this.parent.getShell(), "请在右侧区域选择移动项!", Model.CONFIRM_MODEL).open();
                 return;
             }
             boolean allowable = false;
             if(null == searchShuttleBoxEvent){
                 allowable = true;
             }else if(searchShuttleBoxEvent.deleteEvent(new ArrayList<>(rightSelectMap.keySet()),this)){
                 allowable = true;
             }else{
                 new CustomMessageBox(this.parent.getShell(), "向左侧移动失败!", Model.CONFIRM_MODEL).open();
                 return;
             }
             if(allowable){
                 if(totalCount == 0){  //原先总量为0
                     disposeLeftContentComposite();
                 }
                 for(Entry<T, Composite> entry:rightSelectMap.entrySet()){
                     entry.getValue().dispose();
                     rightDataList.remove(entry.getKey());
                     //左侧绘制一个内容
                     generateComboItem(entry.getKey());
                     this.totalCount++;
                 }
                 rightSelectMap.clear();
                 updateRightNum();
                 updateLeftNum();
                 relayoutScrollComposite();
                 relayoutRightScrollComposite();
             }
        }
        
        /**
         * 将checkbox变成选中状态
         * @param img
         */
        protected void changeSelectCheckBox(Label img) {
            if(img != null){
                img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.CHECKBOX_SELF_ICON)));
                img.setData("checked", true);
            }
        }
        
        /**
         * 将checkbox变成未选中状态
         * @param img
         */
        protected void changeUnSelectCheckBox(Label img) {
            if(null != img){
                img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.CHECKBOX_NOR_ICON)));
                img.setData("checked", false);
            }
        }
        
        /**
         * 设置为选中状态
         * @param itemLabel
         */
        protected void changeItemSelection(CLabel itemLabel) {
            itemLabel.getParent().setBackground(SWTResourceManager.getColor(226, 235, 255));
            Control[] children = itemLabel.getParent().getChildren();
            for (Control child : children) {
                child.setBackground(SWTResourceManager.getColor(226, 235, 255));
            }
        }
        
        /**
         * 设置项为非选中状态
         * @param itemLabel
         */
        protected void changeItemUnSelection(CLabel itemLabel) {
            itemLabel.getParent().setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            Control[] children = itemLabel.getParent().getChildren();
            for (Control child : children) {
                child.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            }
        }
        
        /**
         * 重新绘制左侧滚动区域*/
        protected void relayoutScrollComposite(){
            Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
            searchContentComposite.layout(true);
            Composite scrollContentComposite = searchContentComposite.getParent();
            scrollContentComposite.layout(true);
            searchScrollContentComposite.setMinSize(scrollContentComposite.computeSize(SWT.DEFAULT,SWT.DEFAULT));
        }
        
        /**
         * 重新绘制右侧区域*/
        protected void relayoutRightScrollComposite(){
            this.rightScrolledContentComposite.layout(true);
            ((ScrolledComposite)rightScrolledContentComposite.getParent()).setMinSize(rightScrolledContentComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }
        
        
        /**
         * 销毁左侧*/
        protected void disposeLeftContentComposite(){
            Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
            for(Control child:searchContentComposite.getChildren()){
                child.dispose();
            }
        }
        
        /**
         * 更换左侧内容区域的数字*/
        protected void updateLeftNum(){
            num_label.setText("(当前选中"+this.selectedList.size()+"/"+this.totalCount+")");
            num_label.getParent().layout(true);
        }
        
        /**
         * 更新右侧区域的内容*/
        protected void updateRightNum(){
            right_num_label.setText("("+this.rightDataList.size()+")");
            right_num_label.getParent().layout(true);
        }
        
          /**
         * <p>穿梭框事件</p>
         * @version V1.0
         */
        public interface SearchShuttleBoxEvent<T>{
            /**
             * 添加左侧区域发生的后台逻辑,只有为true,才会将数据移向右侧区域
             * @param addData
             */
            boolean addEvent(List<T> addData,DefinedCommonSearchShuttleBox<T> box);
            /**
             * 将右侧区域数据移向左侧发生的后台事件,只有为true,才会将数据移向左侧区域
             * @param deleteData
             * @return
             */
            boolean deleteEvent(List<T> deleteData,DefinedCommonSearchShuttleBox<T> box);
            /**
             * 
             * @param event
             * @param searchKeys
             * @param pageNum
             * @param pagePerNum
             * @param filters  默认右侧的数据从本次搜索范围剔除,右侧数据在filters的第一个object里面,类型为 List<T>
             * @return
             */
            DefinedSearchText.SearchPageResult<T> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters);
            
            /**
             * 校验输入的搜索条件是否正确
             * @param searchKey
             * @return
             */
             String verifySearchContent(String searchKey);
        }
    
        @Deprecated
        public void reLayoutComboComposite(){
            
        }
        public int getTotalCount() {
            return totalCount;
        }
    
        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }
        
        public List<T> getSelectedList() {
            return selectedList;
        }
        
        public void setSelectedList(List<T> selectedList) {
            this.selectedList = selectedList;
        }
    
        public String getNoContentMention() {
            return noContentMention;
        }
    
        public void setNoContentMention(String noContentMention) {
            this.noContentMention = noContentMention;
        }
    
        public void setLinkEvent(StyleTextLink.StyleTextLinkEvent linkEvent) {
            this.linkEvent = linkEvent;
        }
    
        public void setSearchShuttleBoxEvent(SearchShuttleBoxEvent<T> searchShuttleBoxEvent) {
            this.searchShuttleBoxEvent = searchShuttleBoxEvent;
        }
    
        /**
         * 获取右侧所有数据内容
         * @return
         */
        public List<T> getRightDataList() {
            return rightDataList;
        }
    }

    DefinedCommonSearchShuttleBox.java  穿梭框的公共类,该章节中介绍的自定义穿梭框待搜索功能、且穿梭框分为两类:

    •  分类穿梭框:左侧按照分类进行呈现;
    • 无分类穿梭框:左侧无分类呈现;

    5.1 分类穿梭框

    package com.view.control.shuttlebox;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.custom.CLabel;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Control;
    import org.eclipse.swt.widgets.Event;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.Listener;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.util.CollectionUtil;
    import com.view.control.select.DropDownBox;
    import com.view.swt.CustomMessageBox;
    import com.view.swt.SWTResourceManager;
    import com.view.swt.CustomMessageBox.Model;
    
    /**
     * <p>分类穿梭框控件</p>
     * @version V1.0
     */
    public class DefinedClassifySearchShuttleBox extends DefinedCommonSearchShuttleBox<DefinedClassifySearchShuttleBox.ClassifySearchShuttleData> {
        private static final Logger log = LoggerFactory.getLogger(DefinedClassifySearchShuttleBox.class);
        /***左侧分类中仅能选择一个,不能多选******/
        private boolean classifyUnique;
        
        public DefinedClassifySearchShuttleBox(Composite parent, int comboRowWidth, SearchShuttleBoxEvent<ClassifySearchShuttleData> event) {
            super(parent, null, comboRowWidth);
            this.searchShuttleBoxEvent = event;
        }
        
        /**
         * 获取到数据之后的后续处理*/
        protected void afterSearchClick(Event searchTextEvent,List<DefinedClassifySearchShuttleBox.ClassifySearchShuttleData> searchData){
            boolean append = false;
            if(asynchronous){
                append = true;
            }
            if(searchTextEvent.button == 1){
                Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
                for(Control control:searchContentComposite.getChildren()){
                    control.dispose();
                }
                this.comboDataList.clear();
                searchScrollContentComposite.setMinSize(0, 0);
                totalCount = 0;
            }
            if(CollectionUtil.isNotEmpty(searchData)){
                for(DefinedClassifySearchShuttleBox.ClassifySearchShuttleData data:searchData){
                    if(data != null && CollectionUtil.isNotEmpty(data.getDataList())){
                        totalCount += data.getDataList().size();
                    }
                }
            }
            generateComboContent(append,searchData);
            this.init  = false;
        }
        
        /**
         * 绘制右侧区域的每项
         */
        @SuppressWarnings("unchecked")
        @Override
        void generateRightItem(ClassifySearchShuttleData data) {
            Map<ClassifySearchShuttleData,Composite> classifySearchShuttleDataMap = (Map<ClassifySearchShuttleData, Composite>)rightScrolledContentComposite.getData("data");
            if(null == classifySearchShuttleDataMap){
                classifySearchShuttleDataMap = new HashMap<>();
                rightScrolledContentComposite.setData("data", classifySearchShuttleDataMap);
            }
            Composite itemClassifyComposite = classifySearchShuttleDataMap.get(data);
            if(null == itemClassifyComposite){
                itemClassifyComposite = new Composite(rightScrolledContentComposite,SWT.NONE);
                classifySearchShuttleDataMap.put(data, itemClassifyComposite);
                itemClassifyComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
                GridData gd_classItemComposite = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
                gd_classItemComposite.widthHint = this.comboRowWidth;
                itemClassifyComposite.setLayoutData(gd_classItemComposite);
                GridLayout gl_itemComposite = new GridLayout(1,true);
                gl_itemComposite.verticalSpacing = 0;
                gl_itemComposite.horizontalSpacing = 0;
                gl_itemComposite.marginHeight = 0;
                gl_itemComposite.marginWidth = 0;
                itemClassifyComposite.setLayout(gl_itemComposite);
                itemClassifyComposite.setData("data", data);
                //绘制标题内容
                generateTitleComposite(data.getClassifyName(),itemClassifyComposite);
            }else{
                ClassifySearchShuttleData oriClassifyData = (ClassifySearchShuttleData)itemClassifyComposite.getData("data");
                //需要找出右侧已经存在同类,进行项更换(一个类仅能有一个项存在右侧)
                if(this.classifyUnique){
                    Map<DropDownBox.Data,Composite> itemCompositeList = (Map<DropDownBox.Data,Composite>)itemClassifyComposite.getData("dataComposite");
                    if(CollectionUtil.isNotEmpty(itemCompositeList)){
                        ClassifySearchShuttleData toLeftClassifyData = new ClassifySearchShuttleData();
                        toLeftClassifyData.setClassifyName(oriClassifyData.getClassifyName());
                        toLeftClassifyData.setClassifyValue(oriClassifyData.getClassifyValue());
                        int index = this.rightDataList.indexOf(data);
                        for(Entry<DropDownBox.Data,Composite> entry:itemCompositeList.entrySet()){
                            oriClassifyData.getDataList().remove(entry.getKey());
                            toLeftClassifyData.addData(entry.getKey());
                            itemCompositeList.remove(entry.getKey()).dispose();
                            if(index != -1){
                                this.rightDataList.get(index).getDataList().remove(entry.getKey());
                            }
                        }
                        generateLeftItemComposite(toLeftClassifyData);
                    }
                }
                oriClassifyData.getDataList().addAll(data.getDataList());
            }
            //绘制每项内容
            if(CollectionUtil.isNotEmpty(data.getDataList())){
                for(DropDownBox.Data item:data.getDataList()){
                    generateItemComposite(item,itemClassifyComposite,new Listener(){
                        @Override
                        public void handleEvent(Event event) {
                            Label img = (Label)event.widget;
                            boolean select = (boolean)img.getData("checked");
                            DropDownBox.Data data = (DropDownBox.Data)img.getData("value");
                            if (select) {
                                removeItemSelectEvent(rightSelectMap,data,(ClassifySearchShuttleData)img.getParent().getParent().getData("data"));
                                changeUnSelectCheckBox(img);
                                select = false;
                            } else {
                                addItemSelectEvent(rightSelectMap,data,(ClassifySearchShuttleData)img.getParent().getParent().getData("data"),img.getParent().getParent());
                                changeSelectCheckBox(img);
                                select = true;
                            }
                            img.setData("checked", select);
                            updateRightNum();
                        }
                    });
                }
            }
            int index = this.rightDataList.indexOf(data);
            if(index != -1){
                this.rightDataList.get(index).getDataList().addAll(data.getDataList());
            }else{
                ClassifySearchShuttleData rightClassifyData = new ClassifySearchShuttleData();
                rightClassifyData.setClassifyName(data.getClassifyName());
                rightClassifyData.setClassifyValue(data.getClassifyValue());
                rightClassifyData.getDataList().addAll(data.getDataList());
                this.rightDataList.add(rightClassifyData);
            }
        }
        
        /**
         * 从右侧的选择列表中去掉非选中的项
         * @param rightSelectMap  记录右侧选中的项,key为分类对象,分类对象中的dataList为该分类下选中的项
         * @param itemData   要移除的项
         * @param nowClassifyData  固定值,不可变
         */
        private void removeItemSelectEvent(Map<ClassifySearchShuttleData,Composite> rightSelectMap,DropDownBox.Data itemData,ClassifySearchShuttleData nowClassifyData){
            if(CollectionUtil.isNotEmpty(rightSelectMap)){
                ClassifySearchShuttleData selectClassifyData = null;
                for(Entry<ClassifySearchShuttleData,Composite> entry:rightSelectMap.entrySet()){
                    if(entry.getKey().equals(nowClassifyData)){
                        selectClassifyData = entry.getKey();
                        break;
                    }
                }
                if(null != selectClassifyData && CollectionUtil.isNotEmpty(selectClassifyData.getDataList()) && selectClassifyData.getDataList().contains(itemData)){
                    selectClassifyData.getDataList().remove(itemData);
                }
                if(null == selectClassifyData || CollectionUtil.isEmpty(selectClassifyData.getDataList())){
                    rightSelectMap.remove(selectClassifyData);
                }
            }
        }
        
        /**
         * 从右侧的选择列表中选中项
         * @param rightSelectMap  记录右侧选中的项,key为分类对象,分类对象中的dataList为该分类下选中的项
         * @param itemData  选中的项
         * @param nowClassifyData 固定值,不可变
         */
        private void addItemSelectEvent(Map<ClassifySearchShuttleData,Composite> rightSelectMap,DropDownBox.Data itemData,ClassifySearchShuttleData nowClassifyData,Composite classifyComposite){
            ClassifySearchShuttleData selectClassifyData = null;
            if(CollectionUtil.isNotEmpty(rightSelectMap)){
                for(Entry<ClassifySearchShuttleData,Composite> entry:rightSelectMap.entrySet()){
                    if(entry.getKey().equals(nowClassifyData)){
                        selectClassifyData = entry.getKey();
                        break;
                    }
                }
            }
            if(selectClassifyData == null){
                selectClassifyData = new ClassifySearchShuttleData();
                selectClassifyData.setClassifyName(nowClassifyData.getClassifyName());
                selectClassifyData.setClassifyValue(nowClassifyData.getClassifyValue());
            }
            if(!selectClassifyData.getDataList().contains(itemData)){
                selectClassifyData.getDataList().add(itemData);
            }
            rightSelectMap.put(selectClassifyData, classifyComposite);
        }
        
        
        @SuppressWarnings("unchecked")
        @Override
        protected void rightMoveEvent(Event event){
            if(CollectionUtil.isEmpty(selectedList)){
                new CustomMessageBox(this.parent.getShell(), "请在左侧区域选择移动项!", Model.CONFIRM_MODEL).open();
                return;
            }
            boolean allowable = false;
            if(null == searchShuttleBoxEvent){
                allowable = true;
            }else if(searchShuttleBoxEvent.addEvent(selectedList,this)){
                allowable = true;
            }else{
                log.trace("addEvent cancle move");
                return;
            }
            if(allowable){
                for(Entry<DefinedClassifySearchShuttleBox.ClassifySearchShuttleData, Composite> entry:selectMap.entrySet()){
                    if(null != entry.getValue() && CollectionUtil.isNotEmpty(entry.getKey().getDataList())){
                        Map<DropDownBox.Data,Composite> itemCompositeDataMap = (Map<DropDownBox.Data, Composite>)entry.getValue().getData("dataComposite");
                        if(CollectionUtil.isNotEmpty(itemCompositeDataMap)){
                            for(DropDownBox.Data data:entry.getKey().getDataList()){
                                if(itemCompositeDataMap.containsKey(data)){
                                    itemCompositeDataMap.remove(data).dispose();
                                }
                            }
                        }
                        if(CollectionUtil.isEmpty(itemCompositeDataMap)){
                            entry.getValue().dispose();
                        }
                        this.totalCount-=entry.getKey().getDataList().size();
                    }
                    //右侧绘制一个内容
                    generateRightItem(entry.getKey());
                }
                selectedList.clear();
                selectMap.clear();
                updateRightNum();
                updateLeftNum();
                notifyScrollSearch();
                relayoutScrollComposite();
                relayoutRightScrollComposite();
            }
        }
        
        /**
         * 向左移动触发的事件(绘制界面)
         * @param event
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void leftMoveEvent(Event event){
            if(CollectionUtil.isEmpty(rightSelectMap)){
                 new CustomMessageBox(this.parent.getShell(), "请在右侧区域选择移动项!", Model.CONFIRM_MODEL).open();
                 return;
             }
             boolean allowable = false;
             if(null == searchShuttleBoxEvent){
                 allowable = true;
             }else if(searchShuttleBoxEvent.deleteEvent(new ArrayList<>(rightSelectMap.keySet()),this)){
                 allowable = true;
             }else{
                 log.trace("deleteEvent cancle move");
                 return;
             }
             if(allowable){
                 if(totalCount == 0){  //原先总量为0
                     disposeLeftContentComposite();
                 }
                 for(Entry<ClassifySearchShuttleData, Composite> entry:rightSelectMap.entrySet()){
                     if(null != entry.getValue() && CollectionUtil.isNotEmpty(entry.getKey().getDataList())){
                        Map<DropDownBox.Data,Composite> itemCompositeDataMap = (Map<DropDownBox.Data, Composite>)entry.getValue().getData("dataComposite");
                        if(CollectionUtil.isNotEmpty(itemCompositeDataMap)){
                            for(DropDownBox.Data data:entry.getKey().getDataList()){
                                if(itemCompositeDataMap.containsKey(data)){
                                    itemCompositeDataMap.remove(data).dispose();
                                }
                            }
                        }
                        if(CollectionUtil.isEmpty(itemCompositeDataMap)){
                            entry.getValue().dispose();
                            Map<ClassifySearchShuttleData,Composite> classifySearchShuttleDataMap = (Map<ClassifySearchShuttleData, Composite>)rightScrolledContentComposite.getData("data");
                            if(CollectionUtil.isNotEmpty(classifySearchShuttleDataMap) && classifySearchShuttleDataMap.containsKey(entry.getKey())){
                                classifySearchShuttleDataMap.remove(entry.getKey());
                            }
                        }
                        this.totalCount+=entry.getKey().getDataList().size();
                    }
                     rightDataList.remove(entry.getKey());
                     //左侧绘制一个内容
                     generateLeftItemComposite(entry.getKey());
                 }
                 rightSelectMap.clear();
                 updateRightNum();
                 updateLeftNum();
                 relayoutScrollComposite();
                 relayoutRightScrollComposite();
             }
        } 
        
        /**
         * 将右侧选中的项换回到左侧区域时,右侧区域需要对应生成显示内容
         * @param data  右侧区域选中的项
         */
        private void generateLeftItemComposite(ClassifySearchShuttleData data){
            if(null != data && CollectionUtil.isNotEmpty(data.getDataList())){
                Composite classifyComposite = null;
                for(Control control:comboConenetComposite.getChildren()){
                    if(null != control.getData("data") && ((ClassifySearchShuttleData)control.getData("data")).equals(data)){
                        classifyComposite = (Composite)control;
                        break;
                    }
                }
                if(null == classifyComposite){
                    generateComboItem(data);
                }else{
                    //绘制每项内容
                    for(DropDownBox.Data item:data.getDataList()){
                        generateItemComposite(item,classifyComposite,new Listener(){
                            @Override
                            public void handleEvent(Event event) {
                                Label img = (Label)event.widget;
                                boolean select = (boolean)img.getData("checked");
                                DropDownBox.Data data = (DropDownBox.Data)img.getData("value");
                                if (select) {
                                    removeItemData(data,(ClassifySearchShuttleData)img.getParent().getParent().getData("data"),selectedList,selectMap);
                                    changeUnSelectCheckBox(img);
                                    select = false;
                                } else {
                                    if(classifyUnique){  //若是仅允许一个分类中选中一个,需要将原先选中的取消掉
                                        removeAllClassifyItemData((ClassifySearchShuttleData)img.getParent().getParent().getData("data"),selectedList,selectMap);
                                    }
                                    addItemData(data,img.getParent().getParent(),(ClassifySearchShuttleData)img.getParent().getParent().getData("data"),selectedList,selectMap);
                                    changeSelectCheckBox(img);
                                    select = true;
                                }
                                img.setData("checked", select);
                                updateLeftNum();
                            }
                        });
                    }
                }
            }
        }
    
        @Override
        protected void generateComboItemComposite(ClassifySearchShuttleData data, Composite itemClassifyComposite) {
            //itemComposite 为一个分类的composite,里面应该显示自己的子标题及类中的每个项
            if(null != data && CollectionUtil.isNotEmpty(data.getDataList())){
                GridData gd_itemComposite = (GridData)itemClassifyComposite.getLayoutData();
                gd_itemComposite.heightHint = -1;
                GridLayout gl_itemComposite = new GridLayout(1,true);
                gl_itemComposite.verticalSpacing = 0;
                gl_itemComposite.horizontalSpacing = 0;
                gl_itemComposite.marginHeight = 0;
                gl_itemComposite.marginWidth = 0;
                itemClassifyComposite.setLayout(gl_itemComposite);
                
                //绘制标题内容
                generateTitleComposite(data.getClassifyName(),itemClassifyComposite);
                //绘制每项内容
                for(DropDownBox.Data item:data.getDataList()){
                    generateItemComposite(item,itemClassifyComposite,new Listener(){
                        @Override
                        public void handleEvent(Event event) {
                            Label img = (Label)event.widget;
                            boolean select = (boolean)img.getData("checked");
                            DropDownBox.Data data = (DropDownBox.Data)img.getData("value");
                            if (select) {
                                removeItemData(data,(ClassifySearchShuttleData)itemClassifyComposite.getData("data"),selectedList,selectMap);
                                changeUnSelectCheckBox(img);
                                select = false;
                            } else {
                                if(classifyUnique){  //若是仅允许一个分类中选中一个,需要将原先选中的取消掉
                                    removeAllClassifyItemData((ClassifySearchShuttleData)itemClassifyComposite.getData("data"),selectedList,selectMap);
                                }
                                addItemData(data,itemClassifyComposite,(ClassifySearchShuttleData)itemClassifyComposite.getData("data"),selectedList,selectMap);
                                changeSelectCheckBox(img);
                                select = true;
                            }
                            img.setData("checked", select);
                            updateLeftNum();
                        }
                    });
                }
            }
            itemClassifyComposite.layout(true);
        }
        
        /**
         * 绘制标题区域内容
         * @param title
         * @param itemClassifyComposite
         */
        private void generateTitleComposite(String title,Composite itemClassifyComposite){
            Composite title_composite = new Composite(itemClassifyComposite,SWT.NONE);
            GridData gd_title_composite = new GridData(SWT.FILL,SWT.FILL,true,false,1,1);
            gd_title_composite.heightHint = 35;
            title_composite.setLayoutData(gd_title_composite);
            GridLayout gl_title_composite = new GridLayout(1,true);
            gl_title_composite.marginWidth = 3;
            title_composite.setLayout(gl_title_composite);
            title_composite.setBackground(SWTResourceManager.getColor(245,245,245));
            CLabel title_label = new CLabel(title_composite,SWT.NONE);
            title_label.setBackground(SWTResourceManager.getColor(245,245,245));
            title_label.setForeground(SWTResourceManager.getTextColor());
            GridData gd_title_label = new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
            title_label.setLayoutData(gd_title_label);
            title_label.setText(title);
        }
        
        /**
         * 绘制每个类中的项
         * @param data
         * @param itemComposite
         */
        @SuppressWarnings("unchecked")
        private void generateItemComposite(DropDownBox.Data data,Composite itemClassifyComposite,Listener checkboxListener){
            Composite itemComposite = new Composite(itemClassifyComposite,SWT.NONE);
            itemComposite.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_itemComposite = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
            gd_itemComposite.heightHint = this.comboRowHeight;
            gd_itemComposite.widthHint = this.comboRowWidth-20;
            itemComposite.setLayoutData(gd_itemComposite);
            GridLayout gl_itemComposite = new GridLayout(2,false);
            gl_itemComposite.verticalSpacing = 0;
            gl_itemComposite.horizontalSpacing = 5;
            itemComposite.setLayout(gl_itemComposite);
            Label img = new Label(itemComposite, SWT.NONE);
            GridData gd_img = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
            gd_img.widthHint = 24;
            gd_img.heightHint = 24;
            img.setLayoutData(gd_img);
            img.setData("value", data);
            changeUnSelectCheckBox(img);
            itemComposite.setData("checkbox", img);
            img.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            img.addListener(SWT.MouseDown, checkboxListener);
            
            CLabel itemLabel = new CLabel(itemComposite, SWT.NONE);
            itemLabel.setText(data.getDisplay());
            itemLabel.setData("value", data);
            itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            GridData gd_itemLabel= new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
            itemLabel.setLayoutData(gd_itemLabel);
            itemLabel.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            itemLabel.addListener(SWT.MouseEnter, new Listener() {
                @Override
                public void handleEvent(Event event) {
                    changeItemSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseExit, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    changeItemUnSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseDown, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    Event newEvent = new Event();
                    newEvent.widget = img;
                    img.notifyListeners(SWT.MouseDown, newEvent);
                }
            });
            itemComposite.layout(true);
            Map<DropDownBox.Data,Composite> itemCompositeList = (Map<DropDownBox.Data,Composite>)itemClassifyComposite.getData("dataComposite");
            if(null == itemCompositeList){
                itemCompositeList = new HashMap<DropDownBox.Data,Composite>();
                itemClassifyComposite.setData("dataComposite", itemCompositeList);
            }
            itemCompositeList.put(data,itemComposite);
            itemClassifyComposite.layout(true);
        }
        
        /**
         * 将左侧区域中一个类中所有项更改成非选中状态
         * @param classify    类容器上绑定的类数据,不可变更
         * @param classifyDataList
         * @param classifyDataMap
         */
        @SuppressWarnings("unchecked")
        private void removeAllClassifyItemData(ClassifySearchShuttleData classify,List<ClassifySearchShuttleData> classifyDataList,Map<ClassifySearchShuttleData,Composite> classifyDataMap){
            int index = classifyDataList.indexOf(classify);
            if(index != -1){
                ClassifySearchShuttleData newClassifyData = classifyDataList.get(index);
                Composite classifyComposite = classifyDataMap.get(newClassifyData);
                Map<DropDownBox.Data,Composite> itemDataMap = (Map<DropDownBox.Data, Composite>)classifyComposite.getData("dataComposite");
                if(CollectionUtil.isNotEmpty(newClassifyData.getDataList())){
                    if(CollectionUtil.isNotEmpty(itemDataMap)){
                        for(DropDownBox.Data itemData:newClassifyData.getDataList()){
                            if(itemDataMap.containsKey(itemData)){
                                Composite itemComposite = itemDataMap.get(itemData);
                                Label img = (Label)itemComposite.getData("checkbox");
                                changeUnSelectCheckBox(img);
                                img.setData("checked",false);
                            }
                        }
                    }
                }
            }
            classifyDataList.remove(classify);
            classifyDataMap.remove(classify);
        }
        
        /**
         * 左侧区域取消选中一个分类中的项
         * @param data
         * @param classifyDataList
         * @param classifyDataMap
         */
        private void removeItemData(DropDownBox.Data data,ClassifySearchShuttleData classify,List<ClassifySearchShuttleData> classifyDataList,Map<ClassifySearchShuttleData,Composite> classifyDataMap){
            if(CollectionUtil.isNotEmpty(classifyDataList) && data != null){
                List<ClassifySearchShuttleData> removeClassifySearchShuttleDataList = new ArrayList<>();
                int index = classifyDataList.indexOf(classify);
                if(index != -1){
                    ClassifySearchShuttleData classifyData = classifyDataList.get(index);
                    if(null != classifyData && CollectionUtil.isNotEmpty(classifyData.getDataList()) && classifyData.getDataList().contains(data)){
                        classifyData.getDataList().remove(data);
                        if(CollectionUtil.isEmpty(classifyData.getDataList())){
                            removeClassifySearchShuttleDataList.add(classifyData);
                            classifyDataMap.remove(classifyData);
                        }
                    }
                }else{
                    classifyDataMap.remove(classify);
                }
                if(CollectionUtil.isNotEmpty(removeClassifySearchShuttleDataList)){
                    classifyDataList.removeAll(removeClassifySearchShuttleDataList);
                }
            }
        }
        
        /**
         * 左侧区域选中一个项
         * @param data
         * @param classifyDataList
         * @param classifyDataMap
         */
        private void addItemData(DropDownBox.Data data,Composite classifyComposite,ClassifySearchShuttleData classify,List<ClassifySearchShuttleData> classifyDataList,Map<ClassifySearchShuttleData,Composite> classifyDataMap){
            if(data != null && null != classifyDataList && null != classifyDataMap){
                int index = classifyDataList.indexOf(classify);
                ClassifySearchShuttleData newClassify;
                if(index != -1){
                    newClassify = classifyDataList.get(index);
                }else{
                    newClassify = new ClassifySearchShuttleData();
                    newClassify.setClassifyName(classify.getClassifyName());
                    newClassify.setClassifyValue(classify.getClassifyValue());
                    classifyDataList.add(newClassify);
                }
                List<DropDownBox.Data> itemDataList = newClassify.getDataList();
                if(null == itemDataList){
                    itemDataList = new ArrayList<>();
                    newClassify.setDataList(itemDataList);
                }
                if(!itemDataList.contains(data)){
                    itemDataList.add(data);
                }
                classifyDataMap.put(newClassify, classifyComposite);
            }
        }
        
        /**
         * 更换左侧内容区域的数字*/
        @Override
        protected void updateLeftNum(){
            num_label.setText("(当前选中"+ fixTotalSize(this.selectedList)+"/"+this.totalCount+")");
            num_label.getParent().layout(true);
        }
        
        /**
         * 更换右侧内容区域的数字
         */
        protected void updateRightNum(){
            right_num_label.setText("("+fixTotalSize(this.rightDataList)+")");
            right_num_label.getParent().layout(true);
        }
        
        /**
         * 计算条数
         * @param classifyList
         * @return
         */
        public int fixTotalSize(List<ClassifySearchShuttleData> classifyList){
            int size = 0;
            if(CollectionUtil.isNotEmpty(classifyList)){
                for(ClassifySearchShuttleData classifyData:classifyList){
                    if(null != classifyData && CollectionUtil.isNotEmpty(classifyData.getDataList())){
                        size += classifyData.getDataList().size();
                    }
                }
            }
            return size;
        }
    
        public boolean isClassifyUnique() {
            return classifyUnique;
        }
    
        
        public void setClassifyUnique(boolean classifyUnique) {
            this.classifyUnique = classifyUnique;
        }
    
        /**
         * <p>分类数据</p>
         * @version V1.0
         */
        public static class ClassifySearchShuttleData{
            private String classifyName;
            private String classifyValue;
            private List<DropDownBox.Data> dataList = new ArrayList<>();
            
            public String getClassifyName() {
                return classifyName;
            }
            
            public void setClassifyName(String classifyName) {
                this.classifyName = classifyName;
            }
            
            public String getClassifyValue() {
                return classifyValue;
            }
            
            public void setClassifyValue(String classifyValue) {
                this.classifyValue = classifyValue;
            }
            
            public List<DropDownBox.Data> getDataList() {
                return dataList;
            }
            
            public void setDataList(List<DropDownBox.Data> dataList) {
                this.dataList = dataList;
            }
            
            public void addData(DropDownBox.Data data){
                this.dataList.add(data);
            }
    
            @Override
            public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + ((classifyValue == null)?0:classifyValue.hashCode());
                return result;
            }
    
            @Override
            public boolean equals(Object obj) {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                if (getClass() != obj.getClass())
                    return false;
                ClassifySearchShuttleData other = (ClassifySearchShuttleData)obj;
                if (classifyValue == null) {
                    if (other.classifyValue != null)
                        return false;
                } else if (!classifyValue.equals(other.classifyValue))
                    return false;
                return true;
            }
        }
    }

    5.2 无分类穿梭框

    package com.view.control.shuttlebox;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.custom.CLabel;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Event;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.Listener;
    
    import com.view.control.select.DropDownBox;
    import com.view.swt.SWTResourceManager;
    
    /**
     * <p>
     * 带搜索功能的穿梭框(gridLayout布局)
     * </p>
     * @version V1.0
     */
    public class DefinedSearchShuttleBox extends DefinedCommonSearchShuttleBox<DropDownBox.Data> {
        
        public DefinedSearchShuttleBox(Composite parent,int comboRowWidth,SearchShuttleBoxEvent<DropDownBox.Data> event){
            super(parent, null, comboRowWidth);
            this.searchShuttleBoxEvent = event;
        }
    
        /**
         * 绘制右侧一个item框架
         * @param data
         */
        @Override
        protected void generateRightItem(DropDownBox.Data data){
            Composite itemComposite = new Composite(rightScrolledContentComposite,SWT.NONE);
            itemComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            GridData gd_itemComposite = new GridData(SWT.FILL,SWT.FILL,true,false,1,1);
            gd_itemComposite.heightHint = this.comboRowHeight;
            gd_itemComposite.widthHint = this.comboRowWidth;
            itemComposite.setLayoutData(gd_itemComposite);
            GridLayout gl_itemComposite = new GridLayout(2,false);
            gl_itemComposite.verticalSpacing = 0;
            gl_itemComposite.horizontalSpacing = 5;
            itemComposite.setLayout(gl_itemComposite);
            Label img = new Label(itemComposite, SWT.NONE);
            GridData gd_img = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
            gd_img.widthHint = 24;
            gd_img.heightHint = 24;
            img.setLayoutData(gd_img);
            img.setData("value", data);
            changeUnSelectCheckBox(img);
            img.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            img.addListener(SWT.MouseDown, new Listener() {
                @Override
                public void handleEvent(Event event) {
                    Label img = (Label)event.widget;
                    boolean select = (boolean)img.getData("checked");
                    DropDownBox.Data data = (DropDownBox.Data)img.getData("value");
                    if (select) {
                        rightSelectMap.remove(data);
                        changeUnSelectCheckBox(img);
                        select = false;
                    } else {
                        rightSelectMap.put(data, itemComposite);
                        changeSelectCheckBox(img);
                        select = true;
                    }
                    img.setData("checked", select);
                }
            });
            
            CLabel itemLabel = new CLabel(itemComposite, SWT.NONE);
            itemLabel.setText(data.getDisplay());
            itemLabel.setData("value", data);
            itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            GridData gd_itemLabel= new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
            itemLabel.setLayoutData(gd_itemLabel);
            itemLabel.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            itemLabel.addListener(SWT.MouseEnter, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    changeItemSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseExit, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    changeItemUnSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseDown, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    Event newEvent = new Event();
                    newEvent.widget = img;
                    img.notifyListeners(SWT.MouseDown, newEvent);
                }
            });
            itemComposite.layout(true);
            itemComposite.setData("data", data);
            relayoutRightScrollComposite();
        }
    
        /**
         * 绘制左侧区域每行数据
         */
        @Override
        protected void generateComboItemComposite(DropDownBox.Data data, Composite itemComposite) {
            GridLayout gl_itemComposite = new GridLayout(2,false);
            gl_itemComposite.verticalSpacing = 0;
            gl_itemComposite.horizontalSpacing = 5;
            itemComposite.setLayout(gl_itemComposite);
            Label img = new Label(itemComposite, SWT.NONE);
            GridData gd_img = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
            gd_img.widthHint = 24;
            gd_img.heightHint = 24;
            img.setLayoutData(gd_img);
            img.setData("value", data);
            changeUnSelectCheckBox(img);
            img.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            img.addListener(SWT.MouseDown, new Listener() {
                @Override
                public void handleEvent(Event event) {
                    Label img = (Label)event.widget;
                    boolean select = (boolean)img.getData("checked");
                    DropDownBox.Data data = (DropDownBox.Data)img.getData("value");
                    if (select) {
                        selectedList.remove(data);
                        selectMap.remove(data);
                        changeUnSelectCheckBox(img);
                        select = false;
                    } else {
                        selectedList.add(data);
                        selectMap.put(data, itemComposite);
                        changeSelectCheckBox(img);
                        select = true;
                    }
                    img.setData("checked", select);
                    updateLeftNum();
                }
            });
            
            CLabel itemLabel = new CLabel(itemComposite, SWT.NONE);
            itemLabel.setText(data.getDisplay());
            itemLabel.setData("value", data);
            itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
            GridData gd_itemLabel= new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
            itemLabel.setLayoutData(gd_itemLabel);
            itemLabel.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            itemLabel.addListener(SWT.MouseEnter, new Listener() {
                @Override
                public void handleEvent(Event event) {
                    changeItemSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseExit, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    changeItemUnSelection(itemLabel);
                }
            });
            itemLabel.addListener(SWT.MouseDown, new Listener() {
                
                @Override
                public void handleEvent(Event event) {
                    Event newEvent = new Event();
                    newEvent.widget = img;
                    img.notifyListeners(SWT.MouseDown, newEvent);
                }
            });
            itemComposite.layout(true);
        }
    }
  • 相关阅读:
    百度文库:网站镜像站点解决方案
    百度文库:WEB网站架构分析HTML静态化
    61条面向对象设计的经验原则
    oracle 定时任务例子【项目例子】
    javascript的事件机制(百度文库)
    【转】Oracle回收站(recyclebin)
    java十大低级错误和常见注意点
    JAVA UUID 生成
    Oracle in和exists效率问题分析
    http的长连接和短连接(数据库也一样)
  • 原文地址:https://www.cnblogs.com/sandyflower/p/9750148.html
Copyright © 2011-2022 走看看