自定义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 org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
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.eclipse.swt.widgets.Shell;

import com.global.constant.Constants;
import com.util.CollectionUtil;
import com.util.FileUtil;
import com.view.control.DefinedControl;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil;
import com.view.util.ImageUtil;

/**
 * <p>
 * 多选下拉框的通用逻辑
 * </p>
 * @version V1.0
 */
public class DefinedCommonMultiSelect extends DefinedControl {
    
    /**** 其父框需要是gridLaout布局 *****/
    private Composite choseMaxComposite;
    /**** 选中内容显示的文本区域容器 *****/
    private Composite chooseComposite;
    /*** 下一个item所在的x坐标 ***/
    private int chooseItemNextX = 0;
    /*** 下一个item所在的y坐标 ******/
    private int chooseItemNextY = 0;
    private List<DropDownBox.Data> selectedList = new ArrayList<DropDownBox.Data>();
    /*** 选中内容显示的文本区域实际的宽度 ****/
    private int chooseRealWidth;
    private Map<DropDownBox.Data, Composite> selectedCompositeMap = new LinkedHashMap<DropDownBox.Data, Composite>();
    private Map<DropDownBox.Data, Label> comboImg = new HashMap<DropDownBox.Data, Label>();
    /**** 选中内容显示的文本区域 + 下拉图标 总宽度 ****/
    private int chooseWidth = 323;
    /**** 内容框中的每项的高度 *****/
    private int chooseItemHeight = 24;
    /**** 默认值 ***/
    private List<DropDownBox.Data> defaultValueList = new ArrayList<DropDownBox.Data>();
    private List<DefinedCommonMultiSelectEvent> itemHandlerListener;
    private Label img;
    private DropDownBox<DropDownBox.Data> dropDownBox;
    private Image CHECKBOX_NOR_ICON = ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.CHECKBOX_NOR_ICON));
    private Image CHECKBOX_SELF_ICON = ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.CHECKBOX_SELF_ICON));
    
    public DefinedCommonMultiSelect(Composite parent, DropDownBox<DropDownBox.Data> dropDownBox) {
        super(parent);
        this.dropDownBox = dropDownBox;
    }
    
    public DefinedCommonMultiSelect(Composite parent,int chooseWidth, int chooseItemHeight,
            DropDownBox<DropDownBox.Data> dropDownBox) {
        this(parent, dropDownBox);
        this.chooseWidth = chooseWidth;
        this.chooseItemHeight = chooseItemHeight;
    }
    
    @Override
    public void paint() {
        this.chooseComposite = generateComposite(this.parent);
    }
    
    /**
     * 创建显示下拉框的内容
     * @param contentComposite
     * @return
     */
    protected Composite generateComposite(Composite contentComposite) {
        choseMaxComposite = new Composite(contentComposite, SWT.NONE);
        GridData gd_contentComposite = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
        gd_contentComposite.widthHint = this.chooseWidth;
        choseMaxComposite.setLayoutData(gd_contentComposite);
        GridLayout grid = new GridLayout(2, false);
        grid.horizontalSpacing = 0;
        grid.marginHeight = 1;
        grid.marginWidth = 1;
        choseMaxComposite.setLayout(grid);
        choseMaxComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        SWTUtil.paintBorder(choseMaxComposite, SWTResourceManager.getColor(229, 229, 229));
        dropDownBox.setContentComposite(choseMaxComposite);
        
        Composite text_container_composite = new Composite(choseMaxComposite, SWT.NONE);
        GridData gd_text_container_composite = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
        text_container_composite.setLayoutData(gd_text_container_composite);
        text_container_composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        grid = new GridLayout(1, true);
        grid.horizontalSpacing = 0;
        grid.marginHeight = 2;
        grid.marginWidth = 2;
        text_container_composite.setLayout(grid);
        
        Composite text_composite = new Composite(text_container_composite, SWT.NONE);
        text_composite.setData("rootParent", this.parent);
        GridData gd_text_composite = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
        chooseRealWidth = this.chooseWidth - 6 - 24;
        gd_text_composite.widthHint = chooseRealWidth;
        gd_text_composite.heightHint = this.chooseItemHeight + 4;
        text_composite.setLayoutData(gd_text_composite);
        text_composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        
        if (CollectionUtil.isNotEmpty(defaultValueList)) {
            List<DropDownBox.Data> dataList = new ArrayList<>();
            for (DropDownBox.Data defaultValue: defaultValueList) {
                addUniqueNickName(dataList,defaultValue);
                dataList.add(defaultValue);
                generateChooseItemComposite(text_composite, defaultValue);
            }
        }
        img = new Label(choseMaxComposite, SWT.NONE);
        GridData gd_img = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_img.widthHint = 24;
        gd_img.heightHint = 24;
        img.setLayoutData(gd_img);
        img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.ARROW_DOWN)));
        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) {
                Composite comboComposite = dropDownBox.getComboComposite();
                if(comboComposite !=null && !comboComposite.isDisposed()){
                    dropDownBox.comboDispose();
                }else{
                    dropDownBox.comboPaint();
                }
            }
        });
        choseMaxComposite.layout(true);
        choseMaxComposite.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                dropDownBox.dispose();
            }
        });
        return text_composite;
    }
    
    /**
     * 重命名data的昵称
     * @param dataList
     * @param defaultValue
     * @return
     */
    private boolean addUniqueNickName(List<DropDownBox.Data> dataList,DropDownBox.Data defaultValue){
        if(dataList.contains(defaultValue)){
            dataList.forEach(data->{
                if(data.getValue().equals(defaultValue.getValue()) && data.getNickname()>defaultValue.getNickname()) {
                    defaultValue.setNickname(data.getNickname());
                }
            });
            defaultValue.setNickname(defaultValue.getNickname()+1);
            return true;
        }
        return false;
    }
    
    public Label getImg() {
        return img;
    }
    
    protected void generateChooseItemComposite(DropDownBox.Data data) {
        Composite containerComposite = generateChooseItemComposite(chooseComposite, data);
        Composite parentComposite = containerComposite.getParent();
        parentComposite.layout(true);
        parentComposite.getParent().layout(true);
        parentComposite.getParent().getParent().layout(true);
        parentComposite.getParent().getParent().getParent().layout(true);
    }
    
    /**
     * 生成一个chooseItemComposite
     * @param text_composite
     * @return
     */
    private Composite generateChooseItemComposite(Composite text_composite, DropDownBox.Data data) {
        Composite containerComposite = new Composite(text_composite, SWT.NONE);
        containerComposite.setData("rootParent", this.parent);
        GridLayout gl_containerComposite = new GridLayout(1, true);
        gl_containerComposite.marginHeight = 2;
        gl_containerComposite.marginWidth = 2;
        gl_containerComposite.horizontalSpacing = 0;
        containerComposite.setLayout(gl_containerComposite);
        containerComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        
        Composite itemComposite = new Composite(containerComposite, SWT.NONE);
        itemComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        itemComposite.setBackground(SWTResourceManager.getColor(245, 245, 245));
        SWTUtil.paintBorder(itemComposite, SWTResourceManager.getBorderColor());
        GridLayout gl_itemComposite = new GridLayout(2, false);
        gl_itemComposite.marginHeight = 1;
        gl_itemComposite.marginWidth = 3;
        gl_itemComposite.horizontalSpacing = 2;
        itemComposite.setLayout(gl_itemComposite);
        itemComposite.setData("value", data);
        
        CLabel label = new CLabel(itemComposite, SWT.NONE);
        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1));
        label.setBackground(SWTResourceManager.getColor(245, 245, 245));
        label.setText(data.getDisplay());
        label.setAlignment(SWT.CENTER);
        label.setForeground(SWTResourceManager.getColor(51, 51, 51));
        
        Label img = new Label(itemComposite, SWT.NONE);
        GridData gd_img = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
        gd_img.widthHint = 16;
        gd_img.heightHint = 16;
        img.setLayoutData(gd_img);
        img.setText("X");
        img.setBackground(SWTResourceManager.getColor(245, 245, 245));
        img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
        img.addListener(SWT.MouseDown, new Listener() {
            @Override
            public void handleEvent(Event event) {
                disposeChooseItemComposite(data);
            }
        });
        itemComposite.layout(true);
        
        int containerCompositeWidth = 24 + label.getBounds().width + 4;
        boolean change = false;
        containerComposite.setSize(containerCompositeWidth, this.chooseItemHeight + 4);
        if ((this.chooseRealWidth - this.chooseItemNextX - containerCompositeWidth) < 0) {
            this.chooseItemNextY += this.chooseItemHeight + 4;
            this.chooseItemNextX = 0;
            change = true;
        }
        containerComposite.setLocation(this.chooseItemNextX, this.chooseItemNextY);
        this.chooseItemNextX += containerCompositeWidth;
        
        this.selectedList.add(data);
        this.selectedCompositeMap.put(data, containerComposite);
        containerComposite.layout(true);
        if (change) {
            ((GridData)text_composite.getLayoutData()).heightHint = this.chooseItemNextY + this.chooseItemHeight + 4;
            reLayoutAllParent(text_composite);
            dropDownBox.reLocation();
        }
        
        if (CollectionUtil.isNotEmpty(itemHandlerListener)) {
            for (DefinedCommonMultiSelectEvent event : itemHandlerListener) {
                event.addItemEvent(data, containerComposite);
            }
        }
        return containerComposite;
    }
    
    /**
     * 销毁一个选中文本框中的一项(同时将其在下拉框中的项置为未选中状态)
     * @param data
     */
    protected void disposeChooseItemComposite(DropDownBox.Data data) {
        selectedList.remove(data);
        Composite containerComposite = selectedCompositeMap.get(data);
        Composite beforeComposite = null;
        Composite beforecontainerComposite = null;
        Rectangle bounds;
        int nextX = containerComposite.getBounds().x;
        int nextY = containerComposite.getBounds().y;
        boolean deleteLast = true; // 要删除的是最后一个
        for (Composite leftContainerComposite : selectedCompositeMap.values()) {
            if (leftContainerComposite == containerComposite) {
                beforeComposite = leftContainerComposite;
                continue;
            }
            if (null != beforeComposite) {
                deleteLast = false;
                if ((this.chooseRealWidth - nextX - leftContainerComposite.getBounds().width) < 0) {
                    leftContainerComposite.setLocation(0, nextY + this.chooseItemHeight + 4);
                } else {
                    leftContainerComposite.setLocation(nextX, nextY);
                }
                leftContainerComposite.layout(true);
                bounds = leftContainerComposite.getBounds();
                nextX = bounds.x + bounds.width;
                nextY = bounds.y;
                beforeComposite = leftContainerComposite;
            } else {
                beforecontainerComposite = leftContainerComposite;
            }
        }
        boolean change = false;
        selectedCompositeMap.remove(data);
        if (deleteLast) {
            if (beforecontainerComposite == null) {
                nextX = 0;
                nextY = 0;
            } else {
                nextX = beforecontainerComposite.getBounds().x + beforecontainerComposite.getBounds().width;
                nextY = beforecontainerComposite.getBounds().y;
            }
        }
        chooseItemNextX = nextX;
        if (chooseItemNextY != nextY) {
            change = true;
        }
        chooseItemNextY = nextY;
        Composite parentComposite = containerComposite.getParent();
        Label imgLabel = comboImg.get(data);
        if(imgLabel != null && !imgLabel.isDisposed()){
            changeUnSelectCheckBox(imgLabel);
        }else{
            comboImg.remove(data);
        }
        containerComposite.dispose();
        if (change) {
            if (0 == chooseItemNextY) {
                ((GridData)parentComposite.getLayoutData()).heightHint = this.chooseItemHeight + 4;
            } else
                ((GridData)parentComposite.getLayoutData()).heightHint = chooseItemNextY + this.chooseItemHeight + 4;
            reLayoutAllParent(parentComposite);
            dropDownBox.reLocation();
        }
        if (CollectionUtil.isNotEmpty(itemHandlerListener)) {
            for (DefinedCommonMultiSelectEvent event : itemHandlerListener) {
                event.disposeItemEvent(data, parentComposite);
            }
        }
    }
    
    /**
     * 获取当前的高度
     * @return
     */
    protected int getHeight() {
        return this.chooseItemNextY + this.chooseItemHeight + 4 + 6;
    }
    
    protected Composite getChoseMaxComposite() {
        return choseMaxComposite;
    }
    
    /**
     * 所有的重新绘制
     * @param composite
     */
    private void reLayoutAllParent(Composite composite) {
        Composite contentComposite = composite;
        while(contentComposite != this.parent){
            contentComposite.layout(true);
            contentComposite = contentComposite.getParent();
        }
        contentComposite.layout(true);
        Composite parentComposite = contentComposite.getParent();
        while(!(parentComposite instanceof ScrolledComposite) && !(parentComposite instanceof Shell)){
            parentComposite.layout(true);
            contentComposite = parentComposite;
            parentComposite = parentComposite.getParent();
        }
        if(parentComposite instanceof ScrolledComposite){
            ((ScrolledComposite)parentComposite).setMinSize(contentComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }
    }
    
    /**
     * 将checkbox变成选中状态
     * @param img
     */
    protected void changeSelectCheckBox(Label img) {
        if(img != null &&  !img.isDisposed()){
            img.setImage(CHECKBOX_SELF_ICON);
            img.setData("checked", true);
        }
    }
    
    /**
     * 将checkbox变成未选中状态
     * @param img
     */
    protected void changeUnSelectCheckBox(Label img) {
        if(null != img && !img.isDisposed()){
            img.setImage(CHECKBOX_NOR_ICON);
            img.setData("checked", false);
        }
    }
    
    /**
     * 销毁掉所有已选择的内容*/
    protected void disposeAllChooseItem() {
        while ((CollectionUtil.isNotEmpty(this.selectedList))) {
            this.disposeChooseItemComposite(this.selectedList.get(0));
        }
    }
    
    private 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));
        }
    }
    
    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);
        if (this.selectedList.contains(data)) {
            changeSelectCheckBox(img);
        } else {
            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) {
                    disposeChooseItemComposite(data);
                } else {
                    generateChooseItemComposite(data);
                    changeSelectCheckBox(img);
                }
            }
        });
        addDropDownCheckBoxImg(data, img);
        
        CLabel itemLabel = new CLabel(itemComposite, SWT.NONE);
        if(dropDownBox.showValue){
            itemLabel.setText(data.getDisplay()+"("+data.getValue()+")");
        }else
            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);
    }
    
    private 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 addItemHandlerListener(DefinedCommonMultiSelectEvent itemHandlerListener) {
        if (null == this.itemHandlerListener) {
            this.itemHandlerListener = new ArrayList<DefinedCommonMultiSelectEvent>();
        }
        this.itemHandlerListener.add(itemHandlerListener);
    }
    
    public Composite getChooseComposite() {
        return chooseComposite;
    }
    
    protected List<DropDownBox.Data> getSelectedList() {
        return selectedList;
    }
    
    protected void addDropDownCheckBoxImg(DropDownBox.Data data, Label img) {
        comboImg.put(data, img);
    }
    
    public void setSelectedList(List<DropDownBox.Data> selectedList) {
        this.selectedList = selectedList;
    }
    
    public int getChooseWidth() {
        return chooseWidth;
    }
    
    public void setChooseWidth(int chooseWidth) {
        this.chooseWidth = chooseWidth;
    }
    
    public int getChooseItemHeight() {
        return chooseItemHeight;
    }
    
    public void setChooseItemHeight(int chooseItemHeight) {
        this.chooseItemHeight = chooseItemHeight;
    }
    
    public void setDefaultValueList(List<DropDownBox.Data> defaultValueList) {
        this.defaultValueList = defaultValueList;
    }
    
    /**
     * 获取已经选择的所有值
     */
    @Override
    public Object getValue() {
        // TODO Auto-generated method stub
        return this.selectedList;
    }


    /**
     * <p>
     * 销毁和添加一个选项发生的事件(主要用于保存后台数据时使用)
     * </p>
     * @version V1.0
     */
    public interface DefinedCommonMultiSelectEvent {
        
        /**
         * 
         * @param data
         * @param text_composite   输入框控件,该控件data属性key"rootParent",可以拿到该行控件
         */
        void disposeItemEvent(DropDownBox.Data data, Composite text_composite);
        
        /**
         * 
         * @param data
         * @param text_composite   为输入框中的一个item,该控件data属性key"rootParent",可以拿到该行控件
         */
        void addItemEvent(DropDownBox.Data data, Composite text_composite);
    }
    
}

 DefinedCommonMultiSelect.java 为自定义多选下拉框公共部分

package com.view.control.select;

import java.util.List;

import org.eclipse.swt.widgets.Composite;

import com.view.control.select.DefinedCommonMultiSelect.DefinedCommonMultiSelectEvent;

/**
 * <p>自定义多选择框(parent必须是gridLayout布局)</p>
 * @version V1.0
 */
public class DefinedMultiSelect extends DropDownBox<DropDownBox.Data> {
    private DefinedCommonMultiSelect commonMultiSelect;
    
    public DefinedMultiSelect(Composite parent, List<DropDownBox.Data> comboDataList, int comboRowWidth) {
        super(parent, comboDataList, comboRowWidth);
        commonMultiSelect = new DefinedCommonMultiSelect(parent,this);
    }
    public DefinedMultiSelect(Composite parent,List<Data> comboDataList,int chooseWidth,int chooseItemHeight) {
        this(parent,comboDataList,chooseWidth);
        commonMultiSelect = new DefinedCommonMultiSelect(parent,chooseWidth,chooseItemHeight,this);
    }

    public void paint(){
        commonMultiSelect.paint();
    }
    
    @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();
    }
    
    /**
     * 获取选择的值
     */
    @SuppressWarnings("unchecked")
    public List<DropDownBox.Data> getValue(){
        return (List<DropDownBox.Data>) commonMultiSelect.getValue();
    }
}

DefinedMultiSelect.java 多选下拉框(文本框 + 下拉弹出框)

package com.view.control.select;

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Rectangle;
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 org.eclipse.swt.widgets.Shell;

import com.global.constant.Constants;
import com.util.CollectionUtil;
import com.util.FileUtil;
import com.util.StringUtil;
import com.view.control.DefinedFormControl;
import com.view.control.select.DefinedCommonMultiSelect.DefinedCommonMultiSelectEvent;
import com.view.swt.SWTResourceManager;
import com.view.util.ImageUtil;

/**
 * <p>多选下拉框不可编辑</p>
 * @version V1.0
 */
public class DefinedFormMultiSelect extends DefinedFormControl{
    /****内容容器*****/
    private Composite contentComposite;
    /****显示名称控件****/
    private CLabel name;
    private DefinedMultiSelect multiSelect;
    /****选中内容显示的文本区域 + 下拉图标 总宽度****/
    private int chooseWidth = 323;
    /****内容框中的每项的高度*****/
    private int chooseItemHeight = 24;
    /*****显示名称**********/
    private String nameText;
    /*****设置显示名称控件的宽度*****/
    private int nameWidth = 100;
    /****默认值***/
    private List<DropDownBox.Data> defaultValueList = new ArrayList<>();
    private List<DropDownBox.Data> selectedList = new ArrayList<DropDownBox.Data>();
    private int comboRowWidth;
    private Listener helpListener;
    private Listener selectListener;
    
    public Listener getSelectListener() {
        return selectListener;
    }

    public void setSelectListener(Listener selectListener) {
        this.selectListener = selectListener;
    }

    private List<DefinedCommonMultiSelectEvent> multiSelectEventList;
    private boolean showValue = false;
    
    public DefinedFormMultiSelect(Composite parent,String nameText, List<DropDownBox.Data> comboDataList, int comboRowWidth) {
        super(parent);
        this.nameText = nameText;
        this.selectedList = comboDataList;
        this.comboRowWidth = comboRowWidth;
    }
    
    public DefinedFormMultiSelect(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int chooseWidth,int nameWidth,int chooseItemHeight) {
        this(parent,nameText,comboDataList,chooseWidth);
        this.chooseWidth = chooseWidth;
        this.nameWidth = nameWidth;
        this.chooseItemHeight = chooseItemHeight;
    }
    
    @Override
    public void paint() {
        contentComposite = new Composite(this.parent,SWT.NONE);
        GridData gd_contentComposite = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
        gd_contentComposite.widthHint = this.chooseWidth+nameWidth+2 + (this.helpListener != null? 24:0); //24为帮助图标宽度
        contentComposite.setLayoutData(gd_contentComposite);
        GridLayout gl_contentComposite = new GridLayout((this.helpListener != null? 4:3), false);
        gl_contentComposite.horizontalSpacing = 5;
        gl_contentComposite.verticalSpacing = 0;
        gl_contentComposite.marginHeight = 0;
        contentComposite.setLayout(gl_contentComposite);
        contentComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        
        name = new CLabel(contentComposite,SWT.NONE);
        GridData gd_name = new GridData(SWT.RIGHT, SWT.FILL, false, true, 1, 1);
        gd_name.widthHint = nameWidth - 2;
        name.setLayoutData(gd_name);
        name.setAlignment(SWT.RIGHT);
        if(this.require){
            name.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream("images/asterisk.png")));
        }
        name.setText(nameText);
        name.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        
        multiSelect = new DefinedMultiSelect(contentComposite,this.selectedList,this.comboRowWidth);
        if(this.chooseWidth != 0){
            multiSelect.setChooseWidth(this.chooseWidth);
        }
        if(this.chooseItemHeight != 0){
            multiSelect.setChooseItemHeight(this.chooseItemHeight);
        }
        if(CollectionUtil.isNotEmpty(defaultValueList)){
            multiSelect.setDefaultValueList(defaultValueList);
        }
        multiSelect.setShowValue(showValue);
        multiSelect.addItemHandlerListener(new DefinedCommonMultiSelectEvent() {    
            @Override
            public void disposeItemEvent(DropDownBox.Data data, Composite text_composite) {
                reLayoutAllParent(text_composite);
            }
            
            @Override
            public void addItemEvent(DropDownBox.Data data, Composite text_composite) {
                reLayoutAllParent(text_composite);
            }
        });
        multiSelect.addItemHandlerListener(new DefinedCommonMultiSelectEvent(){

            @Override
            public void disposeItemEvent(DropDownBox.Data data, Composite text_composite) {
                if(CollectionUtil.isEmpty(multiSelect.getValue()) && require){  //为空
                    Composite composite = getMentionComposite();
                    if(composite != null) {
                        showErrorMention("不能为空",composite);
                    }
                    
                }
            }

            @Override
            public void addItemEvent(DropDownBox.Data data, Composite text_composite) {
                Composite composite = getMentionComposite();
                if(null != composite && !composite.isDisposed() && mention != null && !mention.isDisposed()){
                    showNormalMention(composite);
                }
            }
            
        });
        
        if(CollectionUtil.isNotEmpty(multiSelectEventList)){
            for(DefinedCommonMultiSelectEvent event:multiSelectEventList){
                multiSelect.addItemHandlerListener(event);
            }
        }
        
        multiSelect.paint();
        
        if(this.helpListener != null){  //添加帮助图标
            Label help_img = new Label(contentComposite,SWT.NONE);
            help_img.setToolTipText("获取帮助");    
            help_img.setBackground(SWTResourceManager.getWhiteColor());
            help_img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.HELP_NOR)));
            GridData gd_help_img = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
            gd_help_img.widthHint = 24;
            gd_help_img.heightHint = 24;
            help_img.setLayoutData(gd_help_img);
            help_img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
            help_img.addListener(SWT.MouseDown, this.helpListener);
            help_img.addListener(SWT.MouseEnter, new Listener(){
                @Override
                public void handleEvent(Event event) {
                    help_img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.HELP_HOVER)));
                }
            });
            help_img.addListener(SWT.MouseExit, new Listener(){
                @Override
                public void handleEvent(Event event) {
                    help_img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.HELP_NOR)));
                }
            });
        }

        mention = new Label(contentComposite,SWT.WRAP);
        GridData gd_mention = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1);
        if(super.mentionWidth != 0){
            gd_mention.widthHint = super.mentionWidth;
        }else{
            Rectangle bounds = this.parent.getBounds();
            if(bounds.width == 0){
                bounds = this.parent.getParent().getBounds();
            }
            gd_mention.widthHint = bounds.width - nameWidth - this.chooseWidth - 10;
        }
        mention.setLayoutData(gd_mention);
        mention.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        showNormalMention(getMentionComposite());
    }

    /**
     * 所有的重新绘制
     * @param composite
     */
    private void reLayoutAllParent(Composite composite){
        Composite contentComposite = composite;
        while(contentComposite != this.parent){
            contentComposite.layout(true);
            contentComposite = contentComposite.getParent();
        }
        contentComposite.layout(true);
        Composite parentComposite = contentComposite.getParent();
        while(!(parentComposite instanceof ScrolledComposite) && !(parentComposite instanceof Shell)){
            parentComposite.layout(true);
            contentComposite = parentComposite;
            parentComposite = parentComposite.getParent();
        }
        if(parentComposite instanceof ScrolledComposite){
            ((ScrolledComposite)parentComposite).setMinSize(contentComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        }
    }

    
    public void setNameWidth(int nameWidth) {
        this.nameWidth = nameWidth;
    }
    
    public Composite getContentComposite() {
        return contentComposite;
    }
    
    public void setRequire(boolean require) {
        this.require = require;
    }

    public void setMention(Label mention) {
        this.mention = mention;
    }
    
    public void setDefaultMention(String defaultMention) {
        this.defaultMention = defaultMention;
    }
    
    public int getChooseWidth() {
        return chooseWidth;
    }
    
    public void setChooseWidth(int chooseWidth) {
        this.chooseWidth = chooseWidth;
    }
    
    public int getChooseItemHeight() {
        return chooseItemHeight;
    }
    
    public void setChooseItemHeight(int chooseItemHeight) {
        this.chooseItemHeight = chooseItemHeight;
    }
    
    public boolean isValidResult() {
        return validResult;
    }

    public void setValidResult(boolean validResult) {
        this.validResult = validResult;
    }

    public String getDefaultMention() {
        return defaultMention;
    }

    public List<DropDownBox.Data> getDefaultValueList() {
        return defaultValueList;
    }

    public List<DropDownBox.Data> getSelectedList() {
        return selectedList;
    }

    public void setNameText(String nameText) {
        this.nameText = nameText;
    }

    public boolean isShowValue() {
        return showValue;
    }

    public void setShowValue(boolean showValue) {
        this.showValue = showValue;
    }

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

    public void addItemHandlerListener(DefinedCommonMultiSelectEvent itemHandlerListener) {
        if(null == this.multiSelectEventList){
            this.multiSelectEventList = new ArrayList<DefinedCommonMultiSelectEvent>();
        }
        this.multiSelectEventList.add(itemHandlerListener);
    }

    public void setHelpListener(Listener helpListener) {
        this.helpListener = helpListener;
    }


    @Override
    public Composite getMentionComposite() {
        // TODO Auto-generated method stub
        if(null != multiSelect.getChooseComposite()){
            return multiSelect.getChooseComposite().getParent();
        }else{
            return null;
        }
    }

    @Override
    public String getValue() {
        List<DropDownBox.Data> dataList = multiSelect.getValue();
        StringBuilder builder = new StringBuilder();
        for(DropDownBox.Data data:dataList){
            builder.append(data.getValue()).append(",");
        }
        if(StringUtil.isNotNullAndEmpty(builder.toString())){
            builder = builder.deleteCharAt(builder.length()-1);
        }
        return builder.toString();
    }
}

DefinedFormMultiSelect.java 表单多选下拉框(标题 + 多选下拉框 + 提示 + 可选帮助)

带搜索功能的下拉框见下章节。

猜你喜欢

转载自www.cnblogs.com/sandyflower/p/9750085.html