自定义SWT控件三之搜索功能下拉框

3、搜索功能下拉弹出框

package com.view.control.select;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import log.HikLog;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
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.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;
import com.view.control.ImageViewer;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil;

/**
 * <p>带有搜索内容的下拉框</p>
 * @version V1.0
 */
public abstract class SearchDropDown<T> extends DropDownBox<T> {
    private static final Logger log = LoggerFactory.getLogger(SearchDropDown.class);
    /***搜索高度****/
    protected int searchHeight = 50;
    /***搜索默认提示显示****/
    protected String defaultMentionHint;
    /***搜索框*****/
    protected DefinedSearchText<T> searchText;
    /****搜索框事件****/
    protected DefinedSearchText.SearchTextEvent<T> searchTextEvent;
    /***是否异步展示***/
    protected boolean asynchronous = false;
    /***每页显示条数(异步展示时生效)****/
    protected int pagePerNum = 10;
    /***当前页数******/
    protected int pageNumNow = 0;
    /****text文本框的宽度****/
    protected int textWidth = 323;
    /****text文本框的高度*****/
    protected int textHeight = 32;
    /***加载区域的高度****/
    protected int loadHeight = 20;
    protected ScrolledComposite searchScrollContentComposite;
    protected List<Object> searchExternalFilterList;
    /***初始化不触发搜索事件****/
    protected boolean initEmpty = false;
    protected boolean finish = false;
    protected boolean init = true;
    /***总量******/
    protected int totalCount;
    protected CLabel mentionHint;

    @Deprecated
    public SearchDropDown(Composite parent, List<T> comboDataList, int comboRowWidth,DefinedSearchText.SearchTextEvent<T> searchTextEvent) {
        super(parent, comboDataList, comboRowWidth);
        this.textWidth = comboRowWidth-20;
        this.searchTextEvent = searchTextEvent;
    }

    public SearchDropDown(Composite parent,DefinedSearchText.SearchTextEvent<T> searchTextEvent,int comboRowWidth){
        super(parent, new ArrayList<>(), comboRowWidth);
        this.textWidth = comboRowWidth-20;
        this.searchTextEvent = searchTextEvent;
    }

    @Override
    protected void coverComboComposite(){
        GridLayout gl_comboComposite = new GridLayout(1,true);
        gl_comboComposite.marginHeight = 1;
        gl_comboComposite.marginWidth = 1;
        gl_comboComposite.marginBottom = 5;
        gl_comboComposite.verticalSpacing = 0;
        comboComposite.setLayout(gl_comboComposite);
        comboComposite.setSize(this.comboRowWidth + 2, 40 + searchHeight);

        generateSearchCompoiste(comboComposite);
    }

    /**
     * 绘制内容区域
     * @param comboComposite
     */
    protected void generateSearchCompoiste(Composite comboComposite) {
        // 绘制搜索框
        Composite searchComposite = new Composite(comboComposite, SWT.NONE);
        searchComposite.setBackground(SWTResourceManager.getWhiteColor());
        GridData gd_searchComposite = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
        searchComposite.setLayoutData(gd_searchComposite);
        GridLayout gl_searchComposite = new GridLayout(1, true);
        gl_searchComposite.marginWidth = 10;
        gl_searchComposite.marginHeight = 10;
        gl_searchComposite.verticalSpacing = 0;
        gl_searchComposite.horizontalSpacing = 0;
        searchComposite.setLayout(gl_searchComposite);
        searchText = new DefinedSearchText<T>(searchComposite, searchTextEvent, textWidth, textHeight);
        if (asynchronous) {
            searchText.setPagePerNum(pagePerNum);
            searchText.setPageNumNow(pageNumNow);
        }
        searchText.paint();

        mentionHint = new CLabel(searchComposite,SWT.NONE);
        GridData gd_mentionHint = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
        mentionHint.setLayoutData(gd_mentionHint);
        mentionHint.setBackground(SWTResourceManager.getWhiteColor());
        mentionHint.setForeground(SWTResourceManager.getColor(204,204,204));
        if(StringUtil.isNotNullAndEmpty(defaultMentionHint)){
            mentionHint.setText(defaultMentionHint);
        }
        searchComposite.layout(true);

        // 绘制内容区域
        searchScrollContentComposite = new ScrolledComposite(comboComposite, SWT.V_SCROLL);
        searchScrollContentComposite.setExpandHorizontal(true);
        searchScrollContentComposite.setExpandVertical(true);
        searchScrollContentComposite.setBackground(SWTResourceManager.getWhiteColor());
        GridData gd_searchScrollContentComposite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
        searchScrollContentComposite.setLayoutData(gd_searchScrollContentComposite);
        generateSearchContentComposite();
    }

    /**
     * 显示默认提示*/
    protected void showNormalMention(){
        SWTUtil.changeBorderToNormal(searchText.getContentText().getContentText());
        if(StringUtil.isNotNullAndEmpty(defaultMentionHint)){
            mentionHint.setForeground(SWTResourceManager.getColor(200,200,200));
            mentionHint.setText(defaultMentionHint);
        }else{
            mentionHint.setText(StringUtils.EMPTY);
        }
    }

    /**
     * 显示错误信息
     * @param errorText
     */
    protected void showErrorMention(String errorText){
        SWTUtil.changeBorderToRed(searchText.getContentText().getContentText());
        mentionHint.setText(errorText);
        mentionHint.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
    }

    /**
     * 生成搜索区域内容composite*/
    private void generateSearchContentComposite() {
        Composite searchContentComposite = new Composite(searchScrollContentComposite,SWT.NONE);
        searchScrollContentComposite.setContent(searchContentComposite);
        searchContentComposite.setBackground(SWTResourceManager.getWhiteColor());
        GridLayout gl_searchContentComposite = new GridLayout(1, true);
        gl_searchContentComposite.marginWidth = 10;
        gl_searchContentComposite.marginHeight = 0;
        gl_searchContentComposite.verticalSpacing = 0;
        gl_searchContentComposite.horizontalSpacing = 0;
        searchContentComposite.setLayout(gl_searchContentComposite);

        //绘制内容区域
        comboConenetComposite = new Composite(searchContentComposite,SWT.NONE);
        comboConenetComposite.setBackground(SWTResourceManager.getWhiteColor());
        GridData gd_contentComposite = new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
        comboConenetComposite.setLayoutData(gd_contentComposite);
        GridLayout gl_comboConenetComposite = new GridLayout(1,true);
        gl_comboConenetComposite.horizontalSpacing = 0;
        gl_comboConenetComposite.verticalSpacing = 0;
        gl_comboConenetComposite.marginHeight = 0;
        gl_comboConenetComposite.marginWidth = 0;
        comboConenetComposite.setLayout(gl_comboConenetComposite);
        searchScrollContentComposite.setData("searchComposite", comboConenetComposite);

         //绘制加载区域
        if(asynchronous){
            CLabel loadLabel = new CLabel(searchContentComposite,SWT.NONE);
            loadLabel.setBackground(SWTResourceManager.getWhiteColor());
            GridData gd_loadComposite = new GridData(SWT.CENTER,SWT.CENTER,true,false,1,1);
            gd_loadComposite.minimumHeight = loadHeight;
            gd_loadComposite.heightHint = loadHeight;
            gd_loadComposite.exclude = true;
            loadLabel.setLayoutData(gd_loadComposite);
            loadLabel.setVisible(false);
            searchScrollContentComposite.setData("load", loadLabel);
        }

        if (!this.asynchronous) {
//            generateNoPageContent();
        }else if(null != searchTextEvent){
            //获取第一页内容,同时为滚动条添加滚动加载事件
//            generatePageContent(true);
            searchScrollContentComposite.getVerticalBar().addListener(SWT.Selection, new Listener(){
                @Override
                public void handleEvent(Event event) {
                    //滚动事件
                    if(!finish){
                        generatePageContent(false);
                    }
                }
            });
        }else{
            log.error(HikLog.toLog("", "no defined search event"));
        }
    }

    /**
     * 非异步加载数据时,后台查询数据,前台需要显示正在加载中*/
    private void generateNoPageLoadContent(){
        Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
        for(Control control:searchContentComposite.getChildren()){
            control.dispose();
        }
        searchScrollContentComposite.setMinSize(0, 0);
        Composite loadComposite = new Composite(searchContentComposite,SWT.NONE);
        GridData gd_loadCompositel = new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
        loadComposite.setLayoutData(gd_loadCompositel);
        GridLayout gl_loadComposite = new GridLayout(2,false);
        gl_loadComposite.marginHeight = 0;
        gl_loadComposite.marginWidth = 0;
        loadComposite.setLayout(gl_loadComposite);
        loadComposite.setBackground(SWTResourceManager.getWhiteColor());

        CLabel mentionLabel = new CLabel(loadComposite,SWT.NONE);
        GridData gd_mentionLabel = new GridData(SWT.RIGHT,SWT.CENTER,true,true,1,1);
        mentionLabel.setLayoutData(gd_mentionLabel);
        mentionLabel.setText("正在加载数据");
        mentionLabel.setBackground(SWTResourceManager.getWhiteColor());
        ImageViewer ic = new ImageViewer(loadComposite);
        GridData gd_ic = new GridData(SWT.LEFT,SWT.CENTER,false,false,1,1);
        gd_ic.widthHint = 24;
        gd_ic.heightHint = 24;
        ic.setLayoutData(gd_ic);
        ImageLoader loader = new ImageLoader();
        ImageData[] imageDatas = loader.load(FileUtil.loadResourceFileAsStream(Constants.INSTALLING_IMG));
        ic.setImages(imageDatas, loader.repeatCount);
        ic.pack();
        loadComposite.layout(true);
    }

    private void generatePageContent(boolean init){
        this.init = init;
        this.searchText.setSearchExternalFilterList(searchExternalFilterList);
        searchText.notifyMousedownEvent();
    }

    /**
     * 获取到数据之后的后续处理*/
    protected void afterSearchClick(Event searchTextEvent,List<T> 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)){
            totalCount += searchData.size();
        }
        generateComboContent(append,searchData);
        this.init  = false;
    }

    /**
     * 分页加载显示*/
    private void generatePageLoadContent(){
        CLabel loadLabel = (CLabel)searchScrollContentComposite.getData("load");
        GridData gd_loadLabel = (GridData)loadLabel.getLayoutData();
        gd_loadLabel.exclude = false;
        loadLabel.setText("加载中...");
        loadLabel.setVisible(true);
        loadLabel.getParent().layout(true);
    }

    /**
     * 点击搜索按钮之前的加载呈现内容*/
    protected void beforeSearchClick(Event event){
        if(init || event.button == 1){
            searchText.setSearchExternalFilterList(searchExternalFilterList);
        }

        if(this.asynchronous){
            if(init || event.button == 1){  //event.button == 1 表示是点击了搜索按钮
                pageNumNow = 0;
                Composite searchContentComposite = (Composite)searchScrollContentComposite.getData("searchComposite");
                for(Control control:searchContentComposite.getChildren()){
                    control.dispose();
                }
                searchScrollContentComposite.setMinSize(0, 0);
                this.comboDataList.clear();
            }
            pageNumNow++;
            searchText.setPageNumNow(pageNumNow);
            finish = false;
            generatePageLoadContent();
        }else{
            searchText.setPagePerNum(Integer.MAX_VALUE);
            generateNoPageLoadContent();
        }
    }

    /**
     * 在已有数据情况下绘制内容区域(将当前数据全部清空,形成新的下拉数据)
     * @param append 是否是追加显示*/
    protected void generateComboContent(boolean append,List<T> dataList){
        if(searchScrollContentComposite.isDisposed()){
            return;
        }
        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 (this.comboDataList.size() <= 8) {
                comboComposite.setSize(this.comboRowWidth + 2, this.comboRowHeight * this.comboDataList.size() + 40 + searchHeight);
            } else {
                comboComposite.setSize(this.comboRowWidth + 2, this.comboRowHeight * 8 + 40 + searchHeight);
            }
            searchScrollContentComposite.setMinSize(this.comboRowWidth + 2,this.comboRowHeight * this.comboDataList.size());
            if(append){
                CLabel loadLabel = (CLabel)searchScrollContentComposite.getData("load");
                GridData gd_loadLabel = (GridData)loadLabel.getLayoutData();
                gd_loadLabel.exclude = true;
                loadLabel.setVisible(false);
            }
        }else if(!append){   //形成待更新内容
            generateNoContentMentionComposite(searchContentComposite,this.getFilterContent(),this.comboRowWidth-30);
            comboComposite.setSize(this.comboRowWidth + 2, 70 + searchHeight);
        }else{  //异步加载数据的情况
            if(CollectionUtil.isEmpty(this.comboDataList)){
                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;
                comboComposite.setSize(this.comboRowWidth + 2, 70 + searchHeight);
            }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();
    }

    /**
     * 重新绘制左侧滚动区域*/
    private 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 abstract void generateNoContentMentionComposite(Composite searchContentComposite,String searchContent,int width);

    public int getSearchHeight() {
        return searchHeight;
    }

    public void setSearchHeight(int searchHeight) {
        this.searchHeight = searchHeight;
    }

    public boolean isAsynchronous() {
        return asynchronous;
    }

    public void setAsynchronous(boolean asynchronous) {
        this.asynchronous = asynchronous;
    }

    public int getPagePerNum() {
        return pagePerNum;
    }

    public void setPagePerNum(int pagePerNum) {
        this.pagePerNum = pagePerNum;
    }

    public int getTextWidth() {
        return textWidth;
    }

    public void setTextWidth(int textWidth) {
        this.textWidth = textWidth;
    }

    public int getTextHeight() {
        return textHeight;
    }

    public void setTextHeight(int textHeight) {
        this.textHeight = textHeight;
    }

    public void setDefaultMentionHint(String defaultMentionHint) {
        this.defaultMentionHint = defaultMentionHint;
    }

    public void setSearchTextEvent(DefinedSearchText.SearchTextEvent<T> searchTextEvent) {
        this.searchTextEvent = searchTextEvent;
    }

    public void setLoadHeight(int loadHeight) {
        this.loadHeight = loadHeight;
    }

    public List<Object> getSearchExternalFilterList() {
        return searchExternalFilterList;
    }

    /**
     * 添加过滤条件,条件的先后顺序需要用户自己控制*/
    public void addSearchExternalFilter(Object filter){
        if(null == searchExternalFilterList){
            searchExternalFilterList = new LinkedList<Object>();
        }
        searchExternalFilterList.add(filter);
    }

    public boolean replaceSearchExternalFilter(Object filter,int index){
        if(null == searchExternalFilterList){
            searchExternalFilterList = new LinkedList<Object>();
        }
        if(searchExternalFilterList.size() == 0 && index == 0){
            searchExternalFilterList.add(filter);
            return true;
        }
        if(index > searchExternalFilterList.size()-1){
            log.error(HikLog.toLog("", "index > searchExternalFilterList.size()", "index","searchExternalFilterList.size()"),index,searchExternalFilterList.size());
            return false;
        }
        if(index<0){
            log.error(HikLog.toLog("", "index < 0", "index"),index);
            return false;
        }
        searchExternalFilterList.remove(index);
        searchExternalFilterList.add(index, filter);
        return true;
    }

    /**
     * 触发搜索,同时更换下拉框中的内容*/
    public void notifySearch(){
        this.init = true;
        this.searchText.notifyMousedownEvent();
    }

    /**
     * 触发滚动条的下拉异步加载事件*/
    public void notifyScrollSearch(){
        if(this.asynchronous && !this.finish){
            generatePageContent(false);
        }
    }

    public boolean isInitEmpty() {
        return initEmpty;
    }

    public void setInitEmpty(boolean initEmpty) {
        this.initEmpty = initEmpty;
    }

    /**
     * 获取要搜索的内容
     * @return
     */
    protected String getFilterContent(){
        return (String)this.searchText.getValue();
    }

    protected int getTotalCount() {
        return totalCount;
    }
}

SearchDropDown.java  带搜索功能的通用下拉框,继承 DropDown.java。该搜索框搜索出的内容可以是在已查出所有数据基础上进行搜索,也可以是异步的分页搜索。

3.1 带搜索功能的单选下拉框

package com.view.control.select;

import java.util.List;

import log.HikLog;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.util.StringUtil;
import com.view.control.DefinedSearchText;
import com.view.control.select.DefinedCommonSingleSelect.DefinedCommonSingleSelectEvent;
import com.view.swt.StyleTextLink;

/**
 * <p>下拉单选带搜索功能</p>
 * @version V1.0
 */
public class DefinedSearchSingleSelect extends SearchDropDown<DropDownBox.Data> {
    private static final Logger log = LoggerFactory.getLogger(DefinedSearchSingleSelect.class);
    private DefinedCommonSingleSelect commonSingleSelect;
    private StyleTextLink.StyleTextLinkEvent linkEvent;
    private String noContentMention = "您可以更新获取选型数据后再进行查询";
    private String linkText = "更新";
    private SearchSingleSelectEvent searchEvent;

    public DefinedSearchSingleSelect(Composite parent, SearchSingleSelectEvent searchEvent,int comboWidth) {
        super(parent, null, comboWidth);
        commonSingleSelect = new DefinedCommonSingleSelect(parent, this);
        commonSingleSelect.setComboWidth(comboWidth);
        this.searchEvent = searchEvent;
    }

    public DefinedSearchSingleSelect(Composite parent, SearchSingleSelectEvent searchEvent,int comboWidth,
            int comboHeight,boolean showValue) {
        super(parent, null, comboWidth);
        commonSingleSelect = new DefinedCommonSingleSelect(parent, this);
        commonSingleSelect.setComboWidth(comboWidth);
        commonSingleSelect.setComboHeight(comboHeight);
        commonSingleSelect.setShowValue(showValue);
        this.searchEvent = searchEvent;
        this.showValue = showValue;
    }

    @Override
    public void paint() {
        searchTextEvent = new DefinedSearchText.SearchTextEvent<DropDownBox.Data>(){
            @Override
            public DefinedSearchText.SearchPageResult<Data> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters) {
               if(null != searchEvent){
                   return searchEvent.search(event, searchKeys, pageNum, pagePerNum, filters);
               }else{
                   log.error(HikLog.toLog("", "no searchTextEvent"));
                   return null;
               }
            }

            @Override
            public boolean beforeEvent(Event event,String searchKey) {
                if(null != searchEvent){
                    String verifyMsg = searchEvent.verifySearchContent(searchKey);
                    if(StringUtil.isNotNullAndEmpty(verifyMsg)){ //校验不通过
                        showErrorMention(verifyMsg);
                        return false;
                    }else{   //校验通过
                        showNormalMention();
                    }
                }
                beforeSearchClick(event);
                return true;
            }

            @Override
            public void afterEvent(Event event, List<Data> dataList) {
                afterSearchClick(event,dataList);
            }
        };
        commonSingleSelect.paint();
    }

    @Override
    protected void comboPaint(){
        super.comboPaint();
        if(!this.initEmpty){
            super.notifySearch();
        }
    }

    @Override
    protected void generateComboItemComposite(Data data, Composite itemComposite) {
        commonSingleSelect.generateComboItemComposite(data, itemComposite);
    }

    public String getValue() {
        return commonSingleSelect.getValue();
    }

    /**
     * 清除当前选择*/
    public void clearValue() {
        commonSingleSelect.clearValue();
    }

    public int getComboWidth() {
        return commonSingleSelect.getComboWidth();
    }

    public void setComboWidth(int comboWidth) {
        commonSingleSelect.setComboWidth(comboWidth);
    }

    public int getComboHeight() {
        return commonSingleSelect.getComboHeight();
    }

    public void setComboHeight(int comboHeight) {
        commonSingleSelect.setComboHeight(comboHeight);
    }

    public DropDownBox.Data getDefaultValue() {
        return commonSingleSelect.getDefaultValue();
    }

    public void setDefaultValue(DropDownBox.Data defaultValue) {
        commonSingleSelect.setDefaultValue(defaultValue);
    }

    public void setDefaultValue(String defaultValue) {
        commonSingleSelect.setDefaultValue(defaultValue);
    }

    public CLabel getContentText() {
        return commonSingleSelect.getContentText();
    }

    public Label getImg() {
        return commonSingleSelect.getImg();
    }

    public Composite getContentComposite() {
        return commonSingleSelect.getContentComposite();
    }

    /**
     * 设置下拉框是否是可用状态
     * @param enable
     */
    public void setEnabel(boolean enable) {
        commonSingleSelect.setEnabel(enable);
    }

    public void setDropdownBeforeEvent(DefinedCommonSingleSelectEvent dropdownBeforeEvent) {
        commonSingleSelect.setDropdownBeforeEvent(dropdownBeforeEvent);
    }

    public interface SearchSingleSelectEvent{
        public DefinedSearchText.SearchPageResult<Data> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters);
        /**
         * 校验输入的搜索条件是否正确
         * @param searchKey
         * @return
         */
        public String verifySearchContent(String searchKey);
    }

    @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,true,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);
    }

    public void setLinkEvent(StyleTextLink.StyleTextLinkEvent linkEvent) {
        this.linkEvent = linkEvent;
    }
}

DefinedSearchSingleSelect.java (搜索框+下拉框),当搜索不到关键项时,可以给出提示,并链接到别的功能

3.2 带搜索功能的多选框

package com.view.control.select;

import java.util.List;

import log.HikLog;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.util.StringUtil;
import com.view.control.DefinedSearchText;
import com.view.control.select.DefinedCommonMultiSelect.DefinedCommonMultiSelectEvent;
import com.view.swt.StyleTextLink;

public class DefinedSearchMultiSelect extends SearchDropDown<DropDownBox.Data> {
    private static final Logger log = LoggerFactory.getLogger(DefinedSearchMultiSelect.class);
    private DefinedCommonMultiSelect commonMultiSelect;
    private StyleTextLink.StyleTextLinkEvent linkEvent;
    private String noContentMention = "您可以更新获取选型数据后再进行查询";
    private String linkText = "更新";
    private SearchMultiSelectEvent searchEvent;

    public DefinedSearchMultiSelect(Composite parent, SearchMultiSelectEvent searchEvent, int comboRowWidth) {
        super(parent, null, comboRowWidth);
        commonMultiSelect = new DefinedCommonMultiSelect(parent, this);
        commonMultiSelect.setChooseWidth(comboRowWidth);
        this.searchEvent = searchEvent;
    }

    public DefinedSearchMultiSelect(Composite parent, SearchMultiSelectEvent searchEvent, int chooseWidth,
            int chooseItemHeight) {
        super(parent, null, chooseWidth);
        commonMultiSelect = new DefinedCommonMultiSelect(parent, this);
        commonMultiSelect.setChooseWidth(chooseWidth);
        commonMultiSelect.setChooseItemHeight(chooseItemHeight);
        this.searchEvent = searchEvent;
    }

    public void paint(){
        searchTextEvent = new DefinedSearchText.SearchTextEvent<DropDownBox.Data>(){
            @Override
            public DefinedSearchText.SearchPageResult<Data> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters) {
               if(null != searchEvent){
                   return searchEvent.search(event, searchKeys, pageNum, pagePerNum, filters);
               }else{
                   log.error(HikLog.toLog("", "no searchTextEvent"));
                   return null;
               }
            }

            @Override
            public boolean beforeEvent(Event event,String searchKey) {
                if(null != searchEvent){
                    String verifyMsg = searchEvent.verifySearchContent(searchKey);
                    if(StringUtil.isNotNullAndEmpty(verifyMsg)){ //校验不通过
                        showErrorMention(verifyMsg);
                        return false;
                    }else{   //校验通过
                        showNormalMention();
                    }
                }
                beforeSearchClick(event);
                return true;
            }

            @Override
            public void afterEvent(Event event, List<Data> dataList) {
                afterSearchClick(event,dataList);
            }
        };
        commonMultiSelect.paint();
    }

    @Override
    protected void comboPaint(){
        super.comboPaint();
        if(!this.initEmpty){
            super.notifySearch();
        }
    }

    @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,true,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 generateComboItemComposite(Data data, Composite itemComposite) {
        commonMultiSelect.generateComboItemComposite(data, itemComposite);
    }

    public void addItemHandlerListener(DefinedCommonMultiSelectEvent itemHandlerListener) {
        commonMultiSelect.addItemHandlerListener(itemHandlerListener);
    }
    public List<Data> getSelectedList() {
        return commonMultiSelect.getSelectedList();
    }

    public void setSelectedList(List<Data> selectedList) {
        commonMultiSelect.setSelectedList(selectedList);
    }

    public int getChooseWidth() {
        return commonMultiSelect.getChooseWidth();
    }

    public void setChooseWidth(int chooseWidth) {
        commonMultiSelect.setChooseWidth(chooseWidth);
    }

    public int getChooseItemHeight() {
        return commonMultiSelect.getChooseItemHeight();
    }

    public void setChooseItemHeight(int chooseItemHeight) {
        commonMultiSelect.setChooseItemHeight(chooseItemHeight);
    }

    public Composite getChoseMaxComposite() {
        return commonMultiSelect.getChoseMaxComposite();
    }

    public Composite getChooseComposite() {
        return commonMultiSelect.getChooseComposite();
    }

    public void setDefaultValueList(List<DropDownBox.Data> defaultValueList) {
        commonMultiSelect.setDefaultValueList(defaultValueList);
    }

    public int getHeight() {
        return commonMultiSelect.getHeight();
    }

    public void disposeAllChooseItem() {
        commonMultiSelect.disposeAllChooseItem();
    }

    public void setLinkEvent(StyleTextLink.StyleTextLinkEvent linkEvent) {
        this.linkEvent = linkEvent;
    }

    public void setNoContentMention(String noContentMention) {
        this.noContentMention = noContentMention;
    }

    public void setLinkText(String linkText) {
        this.linkText = linkText;
    }

    public interface SearchMultiSelectEvent{
        public DefinedSearchText.SearchPageResult<Data> search(Event event, String searchKeys, int pageNum, int pagePerNum, List<Object> filters);
        /**
         * 校验输入的搜索条件是否正确
         * @param searchKey
         * @return
         */
        public String verifySearchContent(String searchKey);
    }
    /**
     * 获取选择的值
     */
    @SuppressWarnings("unchecked")
    public List<DropDownBox.Data> getValue(){
        return (List<DropDownBox.Data>) commonMultiSelect.getValue();
    }
}

DefinedSearchMultiSelect.java 功能类似3.1

package com.view.swt;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;

import com.util.CollectionUtil;

public class StyleTextLink {

    private List<Point> linkList = new ArrayList<>();
    private Color BLUE;// 链接颜色
    private StyleTextLinkEvent event;
    private StyledText st;

    public StyleTextLink(StyleTextLinkEvent event, StyledText st) {
        this.event = event;
        this.st = st;
    }

    public void ReplaceLink(String linkText) {// 给StyleText加链接样式
        BLUE = SWTResourceManager.getColor(SWT.COLOR_BLUE);
        StringBuffer text = new StringBuffer(st.getText());
        int startLink = text.indexOf(linkText);
        int offset = 0;
        int length = linkText.length();
        while (startLink != -1) {// 循环找出文本内所有连接
            int endLink = startLink + linkText.length();// 判断结束位置
            int start = startLink + offset;
            int end = endLink + offset;
            Point p = new Point(start, end);
            linkList.add(p);
            StyleRange style1 = new StyleRange();// 生成链接的样式
            style1.start = startLink + offset;// 连接开始坐标
            style1.length = length;// 长度
            style1.underline = true;// 下划线
            style1.foreground = BLUE;// 颜色
            style1.underlineStyle = SWT.UNDERLINE_LINK;
            st.setStyleRange(style1);
            text.delete(startLink, endLink);
            int s = text.indexOf(linkText);
            offset += endLink - startLink;
            startLink = s;
        }
        if (event != null) {
            st.addMouseListener(new MouseAdapter() {// 加入鼠标点击链接监听事件

                public void mouseDown(MouseEvent e) {
                    Point p = new Point(e.x, e.y);// 鼠标按下的坐标
                    try {
                        int n = st.getOffsetAtLocation(p);// 找出相对文本的位置
                        StyleRange style = st.getStyleRangeAtOffset(n);
                        if (style != null && style.underline
                                && style.foreground.equals(SWTResourceManager.getColor(SWT.COLOR_BLUE))) {// 判断样式是否是连接的样式
                            if (CollectionUtil.isNotEmpty(linkList)) {
                                for (Point pt : linkList) {
                                    if (pt.x <= n && pt.y >= n) {// 对比坐标位置是否在连接文本范围内
                                        event.linkEvent();
                                        st.getShell().forceFocus();
                                    }
                                }
                            }
                        }
                    } catch (Exception e1) {
                    }
                }
            });
        }
    }

    public interface StyleTextLinkEvent {
        void linkEvent();
    }
}

StyleTextLink.java  呈现搜索框中搜素不到内容的链接

其它下拉框见下章节

原文地址:https://www.cnblogs.com/sandyflower/p/9750111.html

时间: 2024-11-07 09:35:10

自定义SWT控件三之搜索功能下拉框的相关文章

自定义SWT控件二之自定义多选下拉框

2.自定义下拉多选框 package com.view.control.select; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import or

自定义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.

自定义SWT控件一之自定义单选下拉框

一.自定义下拉控件 自定义的下拉框,是自定义样式的,其中的下拉框使用的是独立的window,非复选框的下拉框双击单机其它区域或选择完之后,独立window构成的下拉框会自动消失. package com.view.control.select; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite;

一款可以下拉搜索html下拉框控件

直接上图,组件不错,支持静态和动态搜索,这个只是在原控件上自己修改样式后的,这里主要记录一下,在修改别人控件时,应该如何去封装代码: 原控件:http://ivaynberg.github.com/select2 效果图: 源文件:点击下载

Android基础控件——SwipeRefreshLayout最简单的下拉刷新

还在使用传统的下拉刷新,觉得不够漂亮,怕被产品经理骂吗? 还在忧愁自己技术不够好,不会改造带动画的下拉刷新吗? 那么不要担心,使用SwipeRefreshLayout最简单的下拉刷新,既不失美观又简洁 SwipeRefreshLayout下拉刷新是Google自家的下拉刷新控件,使用过程跟开源库PullToRefresh差不多,废话不多说,开车啦 SwipeRefreshLayout实质上是一个ViewGroup,所以我们将其作为我们的根布局进行演示 经过这个步骤之后,其实在页面上就已经能够下拉

dev 中 字符串转中文拼音缩写,对grid列表进行模糊匹配,grid获取焦点行,gridlookupedit控件用拼音模糊匹配下拉选项

番外篇:. //该方法是将字符串转化为中文拼音的首写字母大写, public static string RemoveSpecialCharacters(string str){try{if (string.IsNullOrWhiteSpace(str)) { return str; }var result = Regex.Replace(str, "[^0-9A-Za-z]", "");if (string.IsNullOrWhiteSpace(result))

带搜索的下拉框Chosen

一:参考 https://harvesthq.github.io/chosen/ Chosen是一个jQuery插件 二:引入js文件 <link href="plug-in/chosen_v1.6.2/chosen.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="plug-in/chosen_

js搜索框 js仿百度搜索 js下拉框 jQuery.Autocomplete使用

做了一个网站,需要根据文本框的输入模糊搜索数据库内容给出提示供用户选择,就找到了jQuery.Autocomplete 效果如下图: 该插件托管在github上,具体地址:https://github.com/agarzola/jQueryAutocompletePlugin 官方的英文文档:http://api.jqueryui.com/autocomplete/ 在使用过程中遇到大坑跟大家说一下. 第一个是插件的数据源问题! 如果要使用服务器的数据源需要在调用autocomplete的时候传

百度搜索设置下拉框的操作

Selenium Webdriver百度搜索设置,代码参照虫师selenium_webdriver(python)第一版中百度搜索框设置的代码 #coding:utf-8 from selenium import webdriver import time dr=webdriver.Ie() dr.get("http://www.baidu.com") dr.find_element_by_link_text("设置").click() #定位父节点后再定位子节点