自定义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;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
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.Listener;
import org.eclipse.swt.widgets.Shell; import com.util.CollectionUtil;
import com.view.control.DefinedControl;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil; /**
* <p>下拉框抽象类。该类主要实现了下拉框的绘制</p>
* @version V1.0
*/
public abstract class DropDownBox<T> extends DefinedControl { protected Composite comboConenetComposite;
/*****下拉框中的数据构成****/
protected List<T> comboDataList;
/*****下拉框每一行的高*******/
protected int comboRowHeight = 32;
/*****下拉框每一行的宽******/
protected int comboRowWidth = -1;
protected List<Listener> selectListener;
/******下拉控件的兄弟控件(绘制下拉框时,该控件必须存在)********/
protected Composite contentComposite;
/*****下拉框(gridLayout布局)******/
protected Shell comboComposite;
protected boolean showValue; /****
* <p>Combo数据对象</p>
* @version V1.0
*/
public static class Data{
private String display;
private String value;
private int nickname; public Data(){ } public Data(String display,String value){
this.display = display;
this.value = value;
}
public String getDisplay() {
return display;
} public void setDisplay(String display) {
this.display = display;
} public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} public int getNickname() {
return nickname;
} public void setNickname(int nickname) {
this.nickname = nickname;
} @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + nickname;
result = prime * result + ((value == null)?0:value.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;
Data other = (Data)obj;
if (nickname != other.nickname)
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
public DropDownBox(Composite parent,List<T> comboDataList,int comboRowWidth) {
super(parent);
this.comboDataList = comboDataList;
this.comboRowWidth = comboRowWidth;
} @Override
public void paint() {
generateComboComposite();
} protected void comboPaint(){
generateComboComposite();
} /**
* 生成下拉框
*/
private void generateComboComposite(){
comboComposite = new Shell(this.contentComposite.getShell(),SWT.NO_TRIM);
comboComposite.setBackground(SWTResourceManager.getWhiteColor());
SWTUtil.paintBorder(comboComposite, SWTResourceManager.getDarkColor());
GridLayout gl = new GridLayout();
gl.marginBottom = 2;
gl.marginTop = 2;
gl.marginRight = 2;
gl.marginLeft = 2;
gl.marginWidth = 0;
gl.marginHeight = 0;
comboComposite.setLayout(gl);
comboComposite.addShellListener(new ShellAdapter() {
public void shellDeactivated(ShellEvent arg0) {
if (comboComposite != null && !comboComposite.isDisposed()) {
comboComposite.dispose();
}
}
});
reLocation();
coverComboComposite();
comboComposite.open();
} protected void comboDispose(){
if(!comboComposite.isDisposed()){
comboComposite.dispose();
}
} /**
* 重新定位下拉框显示坐标
*/
public void reLocation(){
if(comboComposite != null && !comboComposite.isDisposed()){
if(null != contentComposite && !contentComposite.isDisposed()){
Point p = contentComposite.getParent().toDisplay(contentComposite.getLocation());
Point size = contentComposite.getSize();
Rectangle shellRect = new Rectangle(p.x, p.y + size.y+5, size.x, 0);
comboComposite.setLocation(shellRect.x,shellRect.y);
}else{
comboComposite.setLocation(0, 0);
}
}
} /**
* 可覆盖下拉框
*/
protected void coverComboComposite(){
comboComposite.setSize(this.comboRowWidth+2, 180);
ScrolledComposite scrolledComposite = new ScrolledComposite(comboComposite,SWT.V_SCROLL);
GridData gd_scrolledComposite = new GridData(SWT.FILL,SWT.FILL,true,true,1,1);
scrolledComposite.setLayoutData(gd_scrolledComposite);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true); comboConenetComposite = new Composite(scrolledComposite,SWT.NONE);
GridLayout gl_comboComposite = new GridLayout(1,true);
gl_comboComposite.horizontalSpacing = 0;
gl_comboComposite.verticalSpacing = 0;
gl_comboComposite.marginHeight = 1;
gl_comboComposite.marginWidth = 1;
comboConenetComposite.setLayout(gl_comboComposite);
comboConenetComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
scrolledComposite.setContent(comboConenetComposite); if(CollectionUtil.isNotEmpty(this.comboDataList)){
if(this.comboDataList.size()<=8){
comboComposite.setSize(this.comboRowWidth+2, this.comboRowHeight * this.comboDataList.size()+10);
}
for(T data:this.comboDataList){
generateComboItem(data);
}
}else{
comboComposite.setSize(this.comboRowWidth, this.comboRowHeight);
}
comboConenetComposite.layout(true);
scrolledComposite.setMinSize(comboConenetComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
} /**
* 创建一个item
* @param display
* @param value
* @param index
*/
protected void generateComboItem(T data){
Composite itemComposite = new Composite(comboConenetComposite,SWT.NONE);
itemComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
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);
generateComboItemComposite(data,itemComposite);
itemComposite.setData("data", data);
} public void addSelectListener(Listener selectListener) {
if(this.selectListener == null){
this.selectListener = new ArrayList<Listener>();
}
this.selectListener.add(selectListener);
} protected List<Listener> getSelectListener() {
return selectListener;
} /**
* 生成一行
* @param data
* @param itemComposite
*/
protected abstract void generateComboItemComposite(T data,Composite itemComposite); public int getComboRowHeight() {
return comboRowHeight;
} public void setComboRowHeight(int comboRowHeight) {
this.comboRowHeight = comboRowHeight;
} public int getComboRowWidth() {
return comboRowWidth;
} public void setComboRowWidth(int comboRowWidth) {
this.comboRowWidth = comboRowWidth;
} public Composite getComboComposite() {
return comboComposite;
} public List<T> getComboDataList() {
return comboDataList;
} public void addData(T data){
this.comboDataList.add(data);
} public void removeData(Data data){
this.comboDataList.remove(data);
} public void setComboDataList(List<T> comboDataList) {
this.comboDataList = comboDataList;
} public boolean isShowValue() {
return showValue;
} public void setShowValue(boolean showValue) {
this.showValue = showValue;
} public void dispose(){
if(comboComposite!= null && !comboComposite.isDisposed()){
comboComposite.dispose();
}
} public void setContentComposite(Composite contentComposite) {
this.contentComposite = contentComposite;
} public Composite getContentComposite() {
return contentComposite;
}
}

DropDownBox.java  是所有下拉框(单选下拉框、复选下拉框)的基础类。

package com.view.control;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set; import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT;
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.util.CollectionUtil;
import com.util.StringUtil;
import com.view.control.valid.DefinedValidListener;
import com.view.control.valid.IValid;
import com.view.control.valid.RequiredValid;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil; public abstract class DefinedFormControl extends DefinedControl {
protected boolean require;
/****提示信息********/
protected Label mention;
/*****校验结果,值为true,表示校验通过****/
protected boolean validResult = true;
/*****默认提示,主要显示error区域*****/
protected String defaultMention;
protected MultiValueMap validlisteners = MultiValueMap.decorate(new HashMap<Integer,IValid>());
protected Composite validControl;
protected int mentionWidth = 0;
public DefinedFormControl(Composite parent) {
super(parent);
} public boolean notifyValid(){
if(!require && CollectionUtil.isEmpty(validlisteners)){
return true;
}
notifyRequired(getValue());
if(validResult && CollectionUtil.isNotMultiEmpty(validlisteners)){
@SuppressWarnings("unchecked")
Set<Integer> keySet = validlisteners.keySet();
Event event = new Event();
event.widget = validControl;
MultiValueMap excludeListener = MultiValueMap.decorate(new HashMap<Integer,Listener>(), ArrayList.class);
for(Integer key:keySet){
if(CollectionUtil.isNotEmpty(validlisteners.getCollection(key))){
if(validResult){
Listener[] listeners = validControl.getListeners(key);
for(Listener listener:listeners){
if(!(listener instanceof DefinedValidListener)){
excludeListener.put(key, listener);
validControl.removeListener(key, listener);
}
}
validControl.notifyListeners(key, event);
}
}
}
if(CollectionUtil.isNotEmpty(excludeListener)){
for(Object key:excludeListener.keySet()){
for(Object listener:excludeListener.getCollection(key)){
validControl.addListener((Integer)key, (Listener)listener);
}
}
}
}
if(validResult){ }
return validResult;
} public abstract String getValue();
public abstract Composite getMentionComposite(); protected void notifyRequired(String value){
if(require && validResult){
RequiredValid valid = new RequiredValid();
String message = valid.valid(value);
if(StringUtil.isNotNullAndEmpty(message)){
showErrorMention(message,getMentionComposite());
}else{
showNormalMention(getMentionComposite());
}
}
} /**
* 显示错误信息
* @author wangfang5 2018年1月6日 下午9:23:38
* @param errorText
*/
protected void showErrorMention(String errorText,Composite contentComposite){
if(contentComposite != null) {
SWTUtil.changeBorderToRed(contentComposite);
}
mention.setText(errorText);
mention.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
mention.getParent().layout(true);
validResult = false;
} /**
* 显示默认提示
* @author wangfang5 2018年1月9日 下午2:27:16
*/
protected void showNormalMention(Composite contentComposite){
if(contentComposite != null) {
SWTUtil.changeBorderToNormal(contentComposite);
}
if(StringUtil.isNotNullAndEmpty(defaultMention)){
mention.setForeground(SWTResourceManager.getColor(200,200,200));
mention.setText(defaultMention);
}else{
mention.setText(StringUtils.EMPTY);
}
mention.getParent().layout(true);
validResult = true;
} public void setRequire(boolean require) {
this.require = require;
} public void setDefaultMention(String defaultMention) {
this.defaultMention = defaultMention;
} public void setMentionWidth(int mentionWidth) {
this.mentionWidth = mentionWidth;
}
}

DefinedFormControl.java 抽象表单控件

package com.view.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.batik.transcoder.TranscoderException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display; public class ImageUtil { public static Image getImage(String filePath) {
ImageLoader loader = new ImageLoader();
ImageData[] imageData = null;
if(filePath.endsWith("svg") || filePath.endsWith("SVG")){
imageData = getImageSvg(filePath, loader);
}else{
try {
imageData = loader.load(filePath);
} catch (SWTException e) {
return null;
}
}
Image newImage = null;
if (imageData.length > 0) {
newImage = new Image(null, imageData[0]);
}
return newImage;
} public static ImageData[] getImageDatas(String filePath) {
ImageLoader loader = new ImageLoader();
ImageData[] imageData = null;
if(filePath.endsWith("svg") || filePath.endsWith("SVG")){
imageData = getImageSvg(filePath, loader);
}else{
try {
imageData = loader.load(filePath);
} catch (SWTException e) {
return null;
}
}
return imageData;
} private static ImageData[] getImageSvg(String filePath, ImageLoader loader) {
ImageData[] imageData;
String path = filePath.substring(0, filePath.lastIndexOf(".")) + ".png";
File file = new File(path);
Map<String, String> map = new HashMap<String, String>();
FileOutputStream outputStream = null;
try {
file.createNewFile();
outputStream = new FileOutputStream(file);
} catch (IOException e1) {
}
try {
SvgPngConverter.convertToPngByFile(filePath, outputStream, map);
} catch (TranscoderException | IOException e1) {
}
imageData = loader.load(path);
file.delete();
return imageData;
} public static Image getImage(InputStream imageInputStream) {
ImageLoader loader = new ImageLoader();
ImageData[] imageData = loader.load(imageInputStream);
Image newImage = null;
if (imageData.length > 0) {
newImage = new Image(null, imageData[0]);
}
return newImage;
} public static Image getImage(String filePath, int width, int height) {
Image scaled = new Image(Display.getDefault(), width, height);
Image src = getImage(filePath);
if (src == null) {
return null;
}
GC gc = new GC(scaled);
try {
gc.setAdvanced(true); // 打开高级绘图模式
gc.setAntialias(SWT.ON);// 设置消除锯齿
gc.setInterpolation(SWT.HIGH); // 设置插值
gc.drawImage(src, 0, 0, src.getBounds().width, src.getBounds().height, 0, 0, width, height);
} finally {
gc.dispose();
}
return scaled; } public static Image getImage(InputStream imageInputStream, int width, int height) {
Image scaled = new Image(Display.getDefault(), width, height);
Image src = getImage(imageInputStream);
GC gc = new GC(scaled);
try {
gc.setAdvanced(true); // 打开高级绘图模式
gc.setAntialias(SWT.ON);// 设置消除锯齿
gc.setInterpolation(SWT.HIGH); // 设置插值
gc.drawImage(src, 0, 0, src.getBounds().width, src.getBounds().height, 0, 0, width, height);
} finally {
gc.dispose();
}
return scaled;
}
}

ImageUtil.java 图像相关工具类

/*******************************************************************************
* Copyright (c) 2011 Google, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.view.swt; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map; import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display; /**
* Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc.
* <p>
* !!! IMPORTANT !!! Application code must explicitly invoke the <code>dispose()</code> method to release the
* operating system resources managed by cached objects when those objects and OS resources are no longer
* needed (e.g. on application shutdown)
* <p>
* This class may be freely distributed as part of any application or plugin.
* <p>
* @author scheglov_ke
* @author Dan Rubel
*/
public class SWTResourceManager {
////////////////////////////////////////////////////////////////////////////
//
// Color
//
////////////////////////////////////////////////////////////////////////////
private static Map<RGB, Color> m_colorMap = new HashMap<RGB, Color>();
/**
* Returns the system {@link Color} matching the specific ID.
*
* @param systemColorID
* the ID value for the color
* @return the system {@link Color} matching the specific ID
*/
public static Color getColor(int systemColorID) {
Display display = Display.getCurrent();
return display.getSystemColor(systemColorID);
} /**
* 获取border边框颜色
* @author wangfang5 2017年10月21日 下午1:32:01
* @return
*/
public static Color getBorderColor(){
return getColor(new RGB(199,199,199));
} /**
* 获取浅灰色border边框颜色
* @author wangfang5 2018年5月22日 下午2:26:08
* @return
*/
public static Color getLightGreyBorderColor(){
return getColor(new RGB(229,229,229));
} /**
* 获取较深的边框颜色
* @author wangfang5 2018年1月27日 下午2:35:39
* @return
*/
public static Color getDarkColor(){
return getColor(new RGB(199,199,199));
} /**
* 默认的字体颜色
* @author wangfang5 2018年1月29日 下午5:42:26
* @return
*/
public static Color getTextColor(){
return getColor(new RGB(51,51,51));
} /**
* 获取白
* @author wangfang5 2018年1月29日 下午6:49:36
* @return
*/
public static Color getWhiteColor(){
return getColor(new RGB(255,255,255));
} /**
* 获取控件边框颜色
* @author wangfang5 2018年1月12日 下午12:01:12
* @return
*/
public static Color getControlBorderColor(){
return getColor(new RGB(204,204,204));
}
/**
* Returns a {@link Color} given its red, green and blue component values.
*
* @param r
* the red component of the color
* @param g
* the green component of the color
* @param b
* the blue component of the color
* @return the {@link Color} matching the given red, green and blue component values
*/
public static Color getColor(int r, int g, int b) {
return getColor(new RGB(r, g, b));
}
/**
* Returns a {@link Color} given its RGB value.
*
* @param rgb
* the {@link RGB} value of the color
* @return the {@link Color} matching the RGB value
*/
public static Color getColor(RGB rgb) {
Color color = m_colorMap.get(rgb);
if (color == null) {
Display display = Display.getCurrent();
color = new Color(display, rgb);
m_colorMap.put(rgb, color);
}
return color;
}
/**
* Dispose of all the cached {@link Color}'s.
*/
public static void disposeColors() {
for (Color color : m_colorMap.values()) {
color.dispose();
}
m_colorMap.clear();
}
////////////////////////////////////////////////////////////////////////////
//
// Image
//
////////////////////////////////////////////////////////////////////////////
/**
* Maps image paths to images.
*/
private static Map<String, Image> m_imageMap = new HashMap<String, Image>();
/**
* Returns an {@link Image} encoded by the specified {@link InputStream}.
*
* @param stream
* the {@link InputStream} encoding the image data
* @return the {@link Image} encoded by the specified input stream
*/
protected static Image getImage(InputStream stream) throws IOException {
try {
Display display = Display.getCurrent();
ImageData data = new ImageData(stream);
if (data.transparentPixel > 0) {
return new Image(display, data, data.getTransparencyMask());
}
return new Image(display, data);
} finally {
stream.close();
}
}
/**
* Returns an {@link Image} stored in the file at the specified path.
*
* @param path
* the path to the image file
* @return the {@link Image} stored in the file at the specified path
*/
public static Image getImage(String path) {
Image image = m_imageMap.get(path);
if (image == null) {
try {
image = getImage(new FileInputStream(path));
m_imageMap.put(path, image);
} catch (Exception e) {
image = getMissingImage();
m_imageMap.put(path, image);
}
}
return image;
}
/**
* Returns an {@link Image} stored in the file at the specified path relative to the specified class.
*
* @param clazz
* the {@link Class} relative to which to find the image
* @param path
* the path to the image file, if starts with <code>'/'</code>
* @return the {@link Image} stored in the file at the specified path
*/
public static Image getImage(Class<?> clazz, String path) {
String key = clazz.getName() + '|' + path;
Image image = m_imageMap.get(key);
if (image == null) {
try {
image = getImage(clazz.getResourceAsStream(path));
m_imageMap.put(key, image);
} catch (Exception e) {
image = getMissingImage();
m_imageMap.put(key, image);
}
}
return image;
}
private static final int MISSING_IMAGE_SIZE = 10;
/**
* @return the small {@link Image} that can be used as placeholder for missing image.
*/
private static Image getMissingImage() {
Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE);
//
GC gc = new GC(image);
gc.setBackground(getColor(SWT.COLOR_RED));
gc.fillRectangle(0, 0, MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE);
gc.dispose();
//
return image;
}
/**
* Style constant for placing decorator image in top left corner of base image.
*/
public static final int TOP_LEFT = 1;
/**
* Style constant for placing decorator image in top right corner of base image.
*/
public static final int TOP_RIGHT = 2;
/**
* Style constant for placing decorator image in bottom left corner of base image.
*/
public static final int BOTTOM_LEFT = 3;
/**
* Style constant for placing decorator image in bottom right corner of base image.
*/
public static final int BOTTOM_RIGHT = 4;
/**
* Internal value.
*/
protected static final int LAST_CORNER_KEY = 5;
/**
* Maps images to decorated images.
*/
@SuppressWarnings("unchecked")
private static Map<Image, Map<Image, Image>>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY];
/**
* Returns an {@link Image} composed of a base image decorated by another image.
*
* @param baseImage
* the base {@link Image} that should be decorated
* @param decorator
* the {@link Image} to decorate the base image
* @return {@link Image} The resulting decorated image
*/
public static Image decorateImage(Image baseImage, Image decorator) {
return decorateImage(baseImage, decorator, BOTTOM_RIGHT);
}
/**
* Returns an {@link Image} composed of a base image decorated by another image.
*
* @param baseImage
* the base {@link Image} that should be decorated
* @param decorator
* the {@link Image} to decorate the base image
* @param corner
* the corner to place decorator image
* @return the resulting decorated {@link Image}
*/
public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) {
if (corner <= 0 || corner >= LAST_CORNER_KEY) {
throw new IllegalArgumentException("Wrong decorate corner");
}
Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[corner];
if (cornerDecoratedImageMap == null) {
cornerDecoratedImageMap = new HashMap<Image, Map<Image, Image>>();
m_decoratedImageMap[corner] = cornerDecoratedImageMap;
}
Map<Image, Image> decoratedMap = cornerDecoratedImageMap.get(baseImage);
if (decoratedMap == null) {
decoratedMap = new HashMap<Image, Image>();
cornerDecoratedImageMap.put(baseImage, decoratedMap);
}
//
Image result = decoratedMap.get(decorator);
if (result == null) {
Rectangle bib = baseImage.getBounds();
Rectangle dib = decorator.getBounds();
//
result = new Image(Display.getCurrent(), bib.width, bib.height);
//
GC gc = new GC(result);
gc.drawImage(baseImage, 0, 0);
if (corner == TOP_LEFT) {
gc.drawImage(decorator, 0, 0);
} else if (corner == TOP_RIGHT) {
gc.drawImage(decorator, bib.width - dib.width, 0);
} else if (corner == BOTTOM_LEFT) {
gc.drawImage(decorator, 0, bib.height - dib.height);
} else if (corner == BOTTOM_RIGHT) {
gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height);
}
gc.dispose();
//
decoratedMap.put(decorator, result);
}
return result;
}
/**
* Dispose all of the cached {@link Image}'s.
*/
public static void disposeImages() {
// dispose loaded images
{
for (Image image : m_imageMap.values()) {
image.dispose();
}
m_imageMap.clear();
}
// dispose decorated images
for (int i = 0; i < m_decoratedImageMap.length; i++) {
Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[i];
if (cornerDecoratedImageMap != null) {
for (Map<Image, Image> decoratedMap : cornerDecoratedImageMap.values()) {
for (Image image : decoratedMap.values()) {
image.dispose();
}
decoratedMap.clear();
}
cornerDecoratedImageMap.clear();
}
}
}
////////////////////////////////////////////////////////////////////////////
//
// Font
//
////////////////////////////////////////////////////////////////////////////
/**
* Maps font names to fonts.
*/
private static Map<String, Font> m_fontMap = new HashMap<String, Font>();
/**
* Maps fonts to their bold versions.
*/
private static Map<Font, Font> m_fontToBoldFontMap = new HashMap<Font, Font>();
/**
* Returns a {@link Font} based on its name, height and style.
*
* @param name
* the name of the font
* @param height
* the height of the font
* @param style
* the style of the font
* @return {@link Font} The font matching the name, height and style
*/
public static Font getFont(String name, int height, int style) {
return getFont(name, height, style, false, false);
}
/**
* Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline
* flags are also supported.
*
* @param name
* the name of the font
* @param size
* the size of the font
* @param style
* the style of the font
* @param strikeout
* the strikeout flag (warning: Windows only)
* @param underline
* the underline flag (warning: Windows only)
* @return {@link Font} The font matching the name, height, style, strikeout and underline
*/
public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) {
String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline;
Font font = m_fontMap.get(fontName);
if (font == null) {
FontData fontData = new FontData(name, size, style);
if (strikeout || underline) {
try {
Class<?> logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$
Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$
if (logFont != null && logFontClass != null) {
if (strikeout) {
logFontClass.getField("lfStrikeOut").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$
}
if (underline) {
logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$
}
}
} catch (Throwable e) {
System.err.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
font = new Font(Display.getCurrent(), fontData);
m_fontMap.put(fontName, font);
}
return font;
}
/**
* Returns a bold version of the given {@link Font}.
*
* @param baseFont
* the {@link Font} for which a bold version is desired
* @return the bold version of the given {@link Font}
*/
public static Font getBoldFont(Font baseFont) {
Font font = m_fontToBoldFontMap.get(baseFont);
if (font == null) {
FontData fontDatas[] = baseFont.getFontData();
FontData data = fontDatas[0];
font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD);
m_fontToBoldFontMap.put(baseFont, font);
}
return font;
}
/**
* Dispose all of the cached {@link Font}'s.
*/
public static void disposeFonts() {
// clear fonts
for (Font font : m_fontMap.values()) {
font.dispose();
}
m_fontMap.clear();
// clear bold fonts
for (Font font : m_fontToBoldFontMap.values()) {
font.dispose();
}
m_fontToBoldFontMap.clear();
}
////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
////////////////////////////////////////////////////////////////////////////
/**
* Maps IDs to cursors.
*/
private static Map<Integer, Cursor> m_idToCursorMap = new HashMap<Integer, Cursor>();
/**
* Returns the system cursor matching the specific ID.
*
* @param id
* int The ID value for the cursor
* @return Cursor The system cursor matching the specific ID
*/
public static Cursor getCursor(int id) {
Integer key = Integer.valueOf(id);
Cursor cursor = m_idToCursorMap.get(key);
if (cursor == null) {
cursor = new Cursor(Display.getDefault(), id);
m_idToCursorMap.put(key, cursor);
}
return cursor;
}
/**
* Dispose all of the cached cursors.
*/
public static void disposeCursors() {
for (Cursor cursor : m_idToCursorMap.values()) {
cursor.dispose();
}
m_idToCursorMap.clear();
}
////////////////////////////////////////////////////////////////////////////
//
// General
//
////////////////////////////////////////////////////////////////////////////
/**
* Dispose of cached objects and their underlying OS resources. This should only be called when the cached
* objects are no longer needed (e.g. on application shutdown).
*/
public static void dispose() {
disposeColors();
disposeImages();
disposeFonts();
disposeCursors();
}
}

1、自定义单选下拉框

package com.view.control.select;

import org.apache.commons.lang3.StringUtils;
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.util.CollectionUtil;
import com.util.FileUtil;
import com.view.control.DefinedControl;
import com.view.control.select.DropDownBox.Data;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil;
import com.util.ImageUtil; /**
* <p>不可编辑下拉框</p>
* @version V1.0
*/
public class DefinedCommonSingleSelect extends DefinedControl {
/****内容框容器的宽度****/
private int comboWidth = 323;
/****内容框容器的高度*****/
private int comboHeight = 32;
/****内容框容器*****/
private CLabel contentText;
private Label img;
private DropDownBox.Data defaultValue;
private boolean enable = true;
private boolean showValue=false;
private DropDownBox<DropDownBox.Data> dropDownBox;
private DefinedCommonSingleSelectEvent dropdownBeforeEvent;
private Composite contentComposite; public DefinedCommonSingleSelect(Composite parent, DropDownBox<DropDownBox.Data> dropDownBox) {
super(parent);
this.dropDownBox = dropDownBox;
} public DefinedCommonSingleSelect(Composite parent,DropDownBox<DropDownBox.Data> dropDownBox,int comboWidth,int comboHeight) {
this(parent,dropDownBox);
this.comboWidth = comboWidth;
this.comboHeight = comboHeight;
} public DefinedCommonSingleSelect(Composite parent,DropDownBox<DropDownBox.Data> dropDownBox,int comboWidth,int comboHeight,boolean showValue) {
this(parent,dropDownBox,comboWidth,comboHeight);
this.showValue=showValue;
} @Override
public void paint() {
contentText = generateComposite(this.parent);
if(null != this.defaultValue){
if(showValue){
contentText.setText(defaultValue.getDisplay()+"_"+ defaultValue.getValue());
}
else{
contentText.setText(defaultValue.getDisplay());
}
contentText.setData("value", this.defaultValue.getValue());
contentText.setData("data", defaultValue);
}
this.parent.layout(true);
} /**
* 创建文本框控件
* @param parentComposite
* @return
*/
private CLabel generateComposite(Composite parentComposite){
contentComposite = new Composite(parentComposite, SWT.NONE);
GridData gd_contentComposite = new GridData(SWT.FILL,SWT.FILL,false,false,1,1);
gd_contentComposite.widthHint = this.comboWidth;
gd_contentComposite.heightHint = this.comboHeight;
contentComposite.setLayoutData(gd_contentComposite);
GridLayout grid = new GridLayout(2, false);
grid.horizontalSpacing = 1;
grid.verticalSpacing = 0;
grid.marginHeight = 1;
grid.marginWidth = 1;
contentComposite.setLayout(grid);
contentComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
SWTUtil.paintBorder(contentComposite, SWTResourceManager.getColor(229,229,229)); CLabel contentText = new CLabel(contentComposite,SWT.NONE);
GridData gd_contentText = new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1);
contentText.setLayoutData(gd_contentText);
contentText.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); img = new Label(contentComposite, 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("images/h-icon-angle-minimum-down.png")));
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) {
boolean addImgEvent = true;
if(null != dropdownBeforeEvent){
addImgEvent = dropdownBeforeEvent.dropdownBeforeEvent();//展现下拉框之前的操作行为
}
if(addImgEvent){
//绘制下拉框
Composite comboComposite = dropDownBox.getComboComposite();
if(comboComposite !=null && !comboComposite.isDisposed()){
dropDownBox.comboDispose();
}else{
dropDownBox.setContentComposite(contentComposite);
dropDownBox.comboPaint();
}
}
}
});
img.setEnabled(this.enable);
contentComposite.layout(true);
return contentText;
} protected void generateComboItemComposite(Data data, Composite itemComposite) {
GridLayout gl_itemComposite = new GridLayout(1,true);
gl_itemComposite.verticalSpacing = 0;
gl_itemComposite.horizontalSpacing = 0;
gl_itemComposite.marginHeight = 0;
gl_itemComposite.marginWidth = 10;
itemComposite.setLayout(gl_itemComposite);
CLabel itemLabel = new CLabel(itemComposite,SWT.NONE);
itemLabel.setData("data",data);
itemLabel.setAlignment(SWT.LEFT);
GridData gd_itemLabel = new GridData(SWT.FILL,SWT.FILL,true,false,1,1);
itemLabel.setLayoutData(gd_itemLabel);
if(data != null){
if(showValue){
itemLabel.setText(data.getDisplay()+"_"+data.getValue());
}
else{
itemLabel.setText(data.getDisplay());
}
}
itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
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) {
if(null == dropdownBeforeEvent || dropdownBeforeEvent.selectBeforeEvent(data)){
contentText.setText(data.getDisplay());
contentText.setData("value", data.getValue());
contentText.setData("data", data);
if(CollectionUtil.isNotEmpty(dropDownBox.getSelectListener())){
for(Listener listener:dropDownBox.getSelectListener()){
event.data = data;
listener.handleEvent(event);
}
}
}
Composite comboComposite = dropDownBox.getComboComposite();
if(comboComposite !=null && !comboComposite.isDisposed()){
dropDownBox.comboDispose();
}
}
});
} private void changeItemSelection(CLabel itemLabel){
itemLabel.getParent().setBackground(SWTResourceManager.getColor(110,154,255));
itemLabel.setBackground(SWTResourceManager.getColor(110,154,255));
itemLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
} private void changeItemUnSelection(CLabel itemLabel){
itemLabel.getParent().setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
itemLabel.setForeground(SWTResourceManager.getColor(51,51,51));
} public String getValue(){
return (String)this.contentText.getData("value");
} /**
* 清除当前选择*/
public void clearValue(){
this.contentText.setText(StringUtils.EMPTY);
this.contentText.setData("value", null);
this.contentText.setData("data", null);
} public int getComboWidth() {
return comboWidth;
} public void setComboWidth(int comboWidth) {
this.comboWidth = comboWidth;
} public int getComboHeight() {
return comboHeight;
} public void setComboHeight(int comboHeight) {
this.comboHeight = comboHeight;
} public DropDownBox.Data getDefaultValue() {
return defaultValue;
} /**
* 获取当前输入框呈现的值
* @return
*/
public DropDownBox.Data getDataValue(){
return (DropDownBox.Data)this.contentText.getData("data");
} public void setDefaultValue(DropDownBox.Data defaultValue) {
this.defaultValue = defaultValue;
} public void setDefaultValue(String defaultValue) {
this.defaultValue = new DropDownBox.Data(defaultValue,defaultValue);
} public CLabel getContentText() {
return contentText;
} public Label getImg() {
return img;
} public Composite getContentComposite() {
return contentComposite;
} /**
* 设置下拉框是否是可用状态
* @param enable
*/
public void setEnabel(boolean enable){
if(img != null && !img.isDisposed()){
this.enable = enable;
img.setEnabled(enable);
}
} public void setDropdownBeforeEvent(DefinedCommonSingleSelectEvent dropdownBeforeEvent) {
this.dropdownBeforeEvent = dropdownBeforeEvent;
} /**
* <p>通用的接口形式</p>
* @version V1.0
*/
public interface DefinedCommonSingleSelectEvent{
/**
* 打开下拉框之前的操作
* @return
*/
boolean dropdownBeforeEvent();
/**
* 下拉可选之前的操作行为,只有在为true的时候,选择的数据才会生效
* @return
*/
boolean selectBeforeEvent(DropDownBox.Data data);
} public boolean isShowValue() {
return showValue;
} public void setShowValue(boolean showValue) {
this.showValue = showValue;
}
}

DefinedCommonSingleSelect.java 为所有单选(可编辑下拉框、不可编辑下拉框)下拉框的公共部分。

1.1 不可编辑下拉框 ( DefinedSingleSelect.java )(一个输入框 + 一个下拉弹出框)

package com.view.control.select;

import java.util.List;

import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label; import com.view.control.select.DefinedCommonSingleSelect.DefinedCommonSingleSelectEvent; /**
* <p>不可编辑下拉框,parent为绝对布局</p>
* @version V1.0
*/
public class DefinedSingleSelect extends DropDownBox<DropDownBox.Data> {
private DefinedCommonSingleSelect commonSingleSelect; public DefinedSingleSelect(Composite parent, List<Data> comboDataList, int comboRowWidth) {
super(parent, comboDataList, comboRowWidth);
commonSingleSelect = new DefinedCommonSingleSelect(parent,this);
} public DefinedSingleSelect(Composite parent,List<Data> comboDataList,int comboWidth,int comboHeight) {
this(parent,comboDataList,comboWidth);
commonSingleSelect = new DefinedCommonSingleSelect(parent,this,comboWidth,comboHeight);
} public DefinedSingleSelect(Composite parent,List<Data> comboDataList,int comboWidth,int comboHeight,boolean showValue) {
this(parent,comboDataList,comboWidth);
commonSingleSelect = new DefinedCommonSingleSelect(parent,this,comboWidth,comboHeight,showValue);
} @Override
public void paint(){
commonSingleSelect.paint();
} @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 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);
} /**
* 获取当前输入框呈现的值
* @return
*/
public DropDownBox.Data getDataValue(){
return commonSingleSelect.getDataValue();
}
}

1.1.1 表单中的下拉框(DefinedFormSingleSelect.java)(标题 + 不可编辑下拉框 + 右侧提示 + 可选帮助提示)

package com.view.control.select;

import java.util.Arrays;
import java.util.List; import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
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 com.global.constant.Constants;
import com.util.FileUtil;
import com.view.control.DefinedFormControl;
import com.view.control.select.DefinedCommonSingleSelect.DefinedCommonSingleSelectEvent;
import com.view.control.valid.IValid;
import com.view.swt.SWTResourceManager;
import com.view.util.ImageUtil; /**
* <p>不可编辑单选下拉框</p>
* @version V1.0
*/
public class DefinedFormSingleSelect extends DefinedFormControl{
/****内容容器*****/
private Composite contentComposite;
/****显示名称控件****/
private CLabel name;
/*****显示名称**********/
private String nameText;
/*****设置显示名称控件的宽度*****/
private int nameWidth = 100;
/*****该控件中存放的默认值***/
private DropDownBox.Data defaultValue;
private List<DropDownBox.Data> comboDataList;
private DefinedSingleSelect selector;
private int comboRowWidth;
private int comboWidth = 323;
private int comboHeight = 32;
private int comboRowHeight = 32;
private Listener selectListener;
private Listener helpListener;
private boolean enable = true;
private boolean showValue=false;
private DefinedCommonSingleSelectEvent dropdownBeforeEvent; public DefinedFormSingleSelect(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int comboWidth) {
super(parent);
this.nameText = nameText;
this.comboDataList = comboDataList;
this.comboWidth = comboWidth;
} public DefinedFormSingleSelect(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int comboWidth,int nameWidth,int comboHeight) {
this(parent,nameText,comboDataList,comboWidth);
this.comboWidth = comboWidth;
this.nameWidth = nameWidth;
this.comboHeight = comboHeight;
} public DefinedFormSingleSelect(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int comboWidth,int nameWidth,int comboHeight,boolean showValue) {
this(parent,nameText,comboDataList,comboWidth);
this.comboWidth = comboWidth;
this.nameWidth = nameWidth;
this.comboHeight = comboHeight;
this.showValue=showValue;
} @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.heightHint = comboHeight;
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;
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)); 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.LEFT,SWT.LEFT,false,false,1,1);
gd_help_img.widthHint = 26;
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)));
}
});
} selector = new DefinedSingleSelect(contentComposite,this.comboDataList,this.comboWidth,this.comboHeight,showValue);
if(this.comboRowWidth != 0){
selector.setComboRowWidth(this.comboRowWidth);
}
if(this.comboRowHeight!= 0){
selector.setComboRowHeight(this.comboRowHeight);
}
if(null != this.defaultValue){
selector.setDefaultValue(this.defaultValue);
}
if(null != selectListener){
selector.addSelectListener(new Listener(){
@Override
public void handleEvent(Event event) {
showNormalMention(selector.getContentText());
}
});
selector.addSelectListener(selectListener);
}
if(null != dropdownBeforeEvent){
selector.setDropdownBeforeEvent(dropdownBeforeEvent);
}
selector.paint();
selector.setEnabel(enable); 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.comboWidth-90;
}
mention.setLayoutData(gd_mention);
mention.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
showNormalMention(getMentionComposite());
} /**
* 显示错误信息
* @param errorText
*/
public void showErrorMention(String errorText){
super.showErrorMention(errorText, getMentionComposite());
} /**
* 设置成默认信息
* @param text
*/
public void resetNormalDefaultMention(String text){
this.defaultMention = text;
showNormalMention(getMentionComposite());
} /**
* 显示默认提示*/
public void showNormalMention() {
showNormalMention(getMentionComposite());
} public void showNormalMention(String mentionTxt) {
String originalMention = this.defaultMention;
this.defaultMention = mentionTxt;
showNormalMention(getMentionComposite());
this.defaultMention = originalMention;
} public void setNameWidth(int nameWidth) {
this.nameWidth = nameWidth;
} public Composite getContentComposite() {
return contentComposite;
} public void setDefaultMention(String defaultMention) {
this.defaultMention = defaultMention;
} public DropDownBox.Data getDefaultValue() {
return defaultValue;
} public void setDefaultValue(DropDownBox.Data defaultValue) {
this.defaultValue = defaultValue;
} public String getValue(){
return selector.getValue();
} public Label getImg() {
return selector.getImg();
} public void setSelectListener(Listener selectListener) {
this.selectListener = selectListener;
} public void setComboRowHeight(int comboRowHeight) {
this.comboRowHeight = comboRowHeight;
} public void setHelpListener(Listener helpListener) {
this.helpListener = helpListener;
} public void setEnable(boolean enable) {
this.enable = enable;
} public Label getMention() {
return mention;
} public DefinedSingleSelect getSelector() {
return selector;
} public void addValidListener(Integer mouseEvent,IValid ...valid){
if(valid.length != 0){
this.validlisteners.putAll(mouseEvent, Arrays.asList(valid));
}
} public void setDropdownBeforeEvent(DefinedCommonSingleSelectEvent dropdownBeforeEvent) {
this.dropdownBeforeEvent = dropdownBeforeEvent;
} @Override
public Composite getMentionComposite() {
return selector.getContentText();
} /**
* 更换下拉选择框的选择范围
* @param comboDataList
*/
public void setComboDataList(List<DropDownBox.Data> comboDataList){
this.comboDataList = comboDataList;
selector.setComboDataList(comboDataList);
} /**
* 清除选择的内容*/
public void clearValue(){
selector.clearValue();
}
}

1.2 可编辑下拉框 ( DefinedSingleSelectWithText .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.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.Text; import com.util.CollectionUtil;
import com.util.FileUtil;
import com.util.StringUtil;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil;
import com.view.util.ImageUtil; /**
* <p>可编辑下拉框,parent为绝对布局</p>
* @version V1.0
*/
public class DefinedSingleSelectWithText extends DropDownBox<DropDownBox.Data> {
/****内容框容器的宽度****/
private int comboWidth = 323;
/****内容框容器的高度*****/
private int comboHeight = 32;
/****内容框容器*****/
private Text contentText;
private Label img;
private String defaultValue;
private List<Listener> contextListener;
private boolean showImg = true; public DefinedSingleSelectWithText(Composite parent, List<Data> comboDataList, int comboRowWidth) {
super(parent, comboDataList, comboRowWidth);
} public DefinedSingleSelectWithText(Composite parent,List<Data> comboDataList,int comboWidth,int comboHeight) {
this(parent,comboDataList,comboWidth);
this.comboWidth = comboWidth;
this.comboHeight = comboHeight;
} @Override
public void paint(){
contentText = generateComposite(this.parent);
if(StringUtil.isNotNullAndEmpty(this.defaultValue)){
contentText.setText(defaultValue);
}
} /**
* 创建文本框控件
* @param contentComposite
* @return
*/
public Text generateComposite(Composite parentComposite){
contentComposite = new Composite(parentComposite, SWT.NONE);
contentComposite.setBounds(0, 0, this.comboWidth, this.comboHeight);
GridLayout grid = new GridLayout(showImg?2:1, false);
grid.horizontalSpacing = 1;
grid.verticalSpacing = 0;
grid.marginHeight = 1;
grid.marginWidth = 5;
contentComposite.setLayout(grid);
contentComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
SWTUtil.paintBorder(contentComposite, SWTResourceManager.getColor(229,229,229)); Text contentText = new Text(contentComposite,SWT.NONE);
GridData gd_contentText = new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1);
contentText.setLayoutData(gd_contentText);
contentText.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); if(CollectionUtil.isNotEmpty(this.contextListener)){
for(Listener listener:this.contextListener){
contentText.addListener(SWT.Modify,listener);
}
} if(showImg){
img = new Label(contentComposite, 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.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
img.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream("images/h-icon-angle-minimum-down.png")));
img.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
img.addListener(SWT.MouseDown, new Listener(){
@Override
public void handleEvent(Event event) {
//绘制下拉框
if(comboComposite != null && !comboComposite.isDisposed()){
comboDispose();
}else{
comboPaint();
}
}
});
}
contentComposite.layout(true);
return contentText;
} @Override
protected void generateComboItemComposite(Data data, Composite itemComposite) {
CLabel itemLabel = new CLabel(itemComposite,SWT.NONE);
itemLabel.setData("data",data);
itemLabel.setAlignment(SWT.LEFT);
itemLabel.setBounds(10, 0, this.comboRowWidth -10, this.comboRowHeight);
itemLabel.setText(data.getDisplay());
itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
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) {
comboComposite.setVisible(false);
contentText.setText(data.getDisplay());
contentText.setData("value", data.getValue());
}
});
} private void changeItemSelection(CLabel itemLabel){
itemLabel.getParent().setBackground(SWTResourceManager.getColor(110,154,255));
itemLabel.setBackground(SWTResourceManager.getColor(110,154,255));
itemLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
} private void changeItemUnSelection(CLabel itemLabel){
itemLabel.getParent().setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
itemLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
itemLabel.setForeground(SWTResourceManager.getColor(51,51,51));
} public String getValue(){
return (String)this.contentText.getData("value");
} public int getComboWidth() {
return comboWidth;
} public void setComboWidth(int comboWidth) {
this.comboWidth = comboWidth;
} public int getComboHeight() {
return comboHeight;
} public void setComboHeight(int comboHeight) {
this.comboHeight = comboHeight;
} public String getDefaultValue() {
return defaultValue;
} public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
} public Text getContentText() {
return contentText;
} public Label getImg() {
return img;
} public Composite getContentComposite() {
return contentComposite;
} /**
* 添加输入事件
* @param listener
*/
public void addCotextListener(Listener listener) {
if(this.contextListener == null){
this.contextListener = new ArrayList<Listener>();
}
this.contextListener.add(listener);
} public boolean isShowImg() {
return showImg;
} public void setShowImg(boolean showImg) {
this.showImg = showImg;
}
}

1.2.1 表单中的下拉框(DefinedFormSingleSelectWithText .java)(标题 + 可编辑下拉框 + 右侧提示 + 可选帮助提示)

package com.view.control.select;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.lang.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
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 com.global.constant.Constants;
import com.util.CollectionUtil;
import com.util.FileUtil;
import com.util.StringUtil;
import com.view.control.DefinedControl;
import com.view.control.valid.DefinedValidListener;
import com.view.control.valid.IValid;
import com.view.control.valid.RequiredValid;
import com.view.swt.SWTResourceManager;
import com.view.swt.SWTUtil;
import com.view.util.ImageUtil; /**
* <p>可编辑单选下拉框</p>
* @version V1.0
*/
public class DefinedFormSingleSelectWithText extends DefinedControl{
/****内容容器*****/
private Composite contentComposite;
/****显示名称控件****/
private CLabel name;
/****是否是必填项****/
private boolean require;
/****提示信息********/
private Label mention;
/*****显示名称**********/
private String nameText;
/*****设置显示名称控件的宽度*****/
private int nameWidth = 100;
/*****校验结果,值为true,表示校验通过****/
private boolean validResult = true;
/*****默认提示,主要显示error区域*****/
private String defaultMention;
/*****该控件中存放的默认值***/
private String defaultValue;
private List<DropDownBox.Data> comboDataList;
private DefinedSingleSelectWithText selector;
private int comboRowWidth;
private int comboWidth = 323;
private int comboHeight = 32;
private int comboRowHeight = 32;
private Listener contextListener;
private MultiValueMap validlisteners = MultiValueMap.decorate(new HashMap<Integer,IValid>());
private Listener helpListener;
private boolean showImg = true; public DefinedFormSingleSelectWithText(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int comboRowWidth) {
super(parent);
this.nameText = nameText;
this.comboDataList = comboDataList;
this.comboRowWidth = comboRowWidth;
} public DefinedFormSingleSelectWithText(Composite parent,String nameText,List<DropDownBox.Data> comboDataList,int comboWidth,int nameWidth,int comboHeight) {
this(parent,nameText,comboDataList,comboWidth);
this.comboWidth = comboWidth;
this.nameWidth = nameWidth;
this.comboHeight = comboHeight;
} @SuppressWarnings("unchecked")
@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.heightHint = comboHeight;
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;
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)); 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.LEFT,SWT.LEFT,false,false,1,1);
gd_help_img.widthHint = 26;
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)));
}
});
} Composite selectorComposite = new Composite(contentComposite,SWT.NONE);
GridData gd_selectorComposite = new GridData(SWT.LEFT, SWT.FILL, false, false, 1, 1);
gd_selectorComposite.widthHint = this.comboWidth;
gd_selectorComposite.heightHint = this.comboHeight;
selectorComposite.setLayoutData(gd_selectorComposite);
selector = new DefinedSingleSelectWithText(selectorComposite,this.comboDataList,this.comboWidth,this.comboHeight);
if(this.comboRowWidth != 0){
selector.setComboRowWidth(this.comboRowWidth);
}
if(this.comboRowHeight!= 0){
selector.setComboRowHeight(this.comboRowHeight);
}
if(StringUtil.isNotNullAndEmpty(this.defaultValue)){
selector.setDefaultValue(this.defaultValue);
}
if(null != contextListener){
selector.addCotextListener(contextListener);
}
selector.setShowImg(showImg);
selector.paint(); mention = new Label(contentComposite,SWT.WRAP);
GridData gd_mention = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1);
Rectangle bounds = this.parent.getBounds();
if(bounds.width == 0){
bounds = this.parent.getParent().getBounds();
}
gd_mention.widthHint = bounds.width - nameWidth - this.comboWidth-10;
mention.setLayoutData(gd_mention);
mention.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
showNormalMention(); /*****为输入添加事件***************/
if(require){
RequiredValid valid = new RequiredValid();
selector.getContentText().addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent e) {
validResult = true;
} @Override
public void focusLost(FocusEvent e) {
if(validResult){
String message = valid.valid(selector.getContentText().getText());
if(StringUtil.isNotNullAndEmpty(message)){
showErrorMention(message);
}else{
showNormalMention();
}
}
}
});
} if(CollectionUtil.isNotMultiEmpty(validlisteners)){
selector.getContentText().addListener(SWT.Modify, new Listener(){
@Override
public void handleEvent(Event event) {
validResult = true;
}
});;
Set<Integer> keySet = validlisteners.keySet();
Iterator<IValid> iterator = null;
IValid valid = null;
for(Integer key:keySet){
if(CollectionUtil.isNotEmpty(validlisteners.getCollection(key))){
iterator = validlisteners.getCollection(key).iterator();
while(iterator.hasNext()){
valid = iterator.next();
selector.getContentText().addListener(key, new DefinedValidListener(valid){
@Override
public void handleEvent(Event event) {
if(validResult){
String message = this.getValid().valid(selector.getValue());
if(StringUtil.isNotNullAndEmpty(message)){
showErrorMention(message);
}else{
showNormalMention();
}
}
}
});
}
}
}
}
} /**
* 显示错误信息
* @param errorText
*/
private void showErrorMention(String errorText){
SWTUtil.changeBorderToRed(selector.getContentComposite());
mention.setText(errorText);
mention.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
mention.getParent().layout(true);
validResult = false;
} /**
* 显示默认提示*/
private void showNormalMention(){
SWTUtil.changeBorderToNormal(selector.getContentComposite());
if(StringUtil.isNotNullAndEmpty(defaultMention)){
mention.setForeground(SWTResourceManager.getColor(200,200,200));
mention.setText(defaultMention);
}else{
mention.setText(StringUtils.EMPTY);
}
mention.getParent().layout(true);
validResult = true;
} public void addValidListener(Integer mouseEvent,IValid ...valid){
if(valid.length != 0){
this.validlisteners.putAll(mouseEvent, Arrays.asList(valid));
}
} public boolean notifyValid(){
if(CollectionUtil.isNotMultiEmpty(validlisteners)){
@SuppressWarnings("unchecked")
Set<Integer> keySet = validlisteners.keySet();
Event event = new Event();
event.widget = selector.getContentText();
MultiValueMap excludeListener = MultiValueMap.decorate(new HashMap<Integer,Listener>(), ArrayList.class);
for(Integer key:keySet){
if(CollectionUtil.isNotEmpty(validlisteners.getCollection(key))){
if(validResult){
Listener[] listeners = selector.getContentText().getListeners(key);
for(Listener listener:listeners){
if(!(listener instanceof DefinedValidListener)){
excludeListener.put(key, listener);
selector.getContentText().removeListener(key, listener);
}
}
selector.getContentText().notifyListeners(key, event);
}
}
}
if(CollectionUtil.isNotEmpty(excludeListener)){
for(Object key:excludeListener.keySet()){
for(Object listener:excludeListener.getCollection(key)){
selector.getContentText().addListener((Integer)key, (Listener)listener);
}
}
}
}
return validResult;
} 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 String getDefaultValue() {
return defaultValue;
} public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
} public String getValue(){
return selector.getContentText().getText();
} public Label getImg() {
return selector.getImg();
} public void setContextListener(Listener listener) {
this.contextListener = listener;
} public void setComboRowHeight(int comboRowHeight) {
this.comboRowHeight = comboRowHeight;
} public DefinedSingleSelectWithText getSelector() {
return selector;
} public Composite getComboComposite() {
return selector.getComboComposite();
} public void setComboDataList(List<DropDownBox.Data> comboDataList) {
this.comboDataList = comboDataList;
} public void setHelpListener(Listener helpListener) {
this.helpListener = helpListener;
} public boolean isShowImg() {
return showImg;
} public void setShowImg(boolean showImg) {
this.showImg = showImg;
}
}

关于多选下拉框、带搜索功能的下拉框见下章节。

上一篇:PropertyGrid控件由浅入深(二):基础用法


下一篇:C# PropertyGrid控件应用心得