自定义SWT控件一之自定义单选下拉框
一、自定义下拉控件
自定义的下拉框,是自定义样式的,其中的下拉框使用的是独立的window,非复选框的下拉框双击单机其它区域或选择完之后,独立window构成的下拉框会自动消失。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | 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; } }
关于多选下拉框、带搜索功能的下拉框见下章节。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~