使用SWT实现图片预览

使用SWT实现图片预览

工作中需要使用swt进行需求开发:给出一组图片,能够预览等其他操作。
将图片预览相关代码单独拿出,创建测试项目,能够实现根据行列数创建图片展示窗口,并能够自适应窗口大小及图片居中,异步添加图片不阻塞窗口等功能。记录起来供今后或他人参考。

  1. 首先列出效果图

    封装了一个用于展示图片的类,根据构造方法可以设置显示的行数及列数。根据设置的宽高进行自适应,可以实现滚动条,选择,查看,全选,反选,图片大小自适应等其他操作。

  2. 封装类代码

package name.hanenhao.ui;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;

import name.hanenhao.entity.FileMeta;

public class ImageViewer extends ScrolledComposite {

	int width = 433;
	int height = 335;

	ImageViewer imageViewer = this;

	ImageDraw imageDraw;

	private Composite composite;

	// 水平滚动条
	private ScrollBar horizontalBar = this.getHorizontalBar();
	// 垂直滚动条
	private ScrollBar verticalBar = this.getVerticalBar();

	private ExecutorService executorService = Executors.newSingleThreadExecutor();

	List<ImageDraw> imageDraws = Collections.synchronizedList(new ArrayList<ImageDraw>());

	int xCount;
	int yCount;

	public ImageViewer(Composite parent, int style) {
		this(parent, style, 2, 2);
	}

	public ImageViewer(Composite parent, int style, int xCount, int yCount) {
		// 样式不能为0 否则不会创建滚动条
		super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL);
		this.setLayout(new FillLayout());
		this.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
		composite = new Composite(this, SWT.NONE);
		composite.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
		this.setContent(composite);
		RowLayout layout = new RowLayout();
		composite.setLayout(layout);
		horizontalBar.setIncrement(15);
		verticalBar.setIncrement(15);
		this.compositeComputeSize();
		this.xCount = xCount;
		this.yCount = yCount;
	}

	public List<ImageDraw> getImageDraws(Boolean isCheck) {
		if (isCheck == null) {
			return this.imageDraws;
		}
		List<ImageDraw> draws = new ArrayList<ImageViewer.ImageDraw>();
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection() == isCheck) {
				draws.add(draw);
			}
		}
		return draws;
	}

	public int count(Boolean isCheck) {
		if (isCheck == null) {
			return this.imageDraws.size();
		}
		int size = 0;
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection() == isCheck) {
				size++;
			}
		}
		return size;
	}

	public List<String> getFileIds(Boolean isCheck) {
		List<String> fileIdOrNames = new ArrayList<String>();
		for (ImageDraw draw : imageDraws) {
			if (isCheck == null) {
				String id = getId(draw);
				if (id != null) {
					fileIdOrNames.add(id);
				}
				continue;
			}
			if (draw.checkBox.getSelection() == isCheck) {
				String id = getId(draw);
				if (id != null) {
					fileIdOrNames.add(id);
				}

			}
		}
		return fileIdOrNames;
	}

	List<String> getSelectFile() {
		return getFileIds(true);
	}

	List<FileMeta> getFileMetaDatas(Boolean isCheck) {
		List<FileMeta> fileMetas = new ArrayList<FileMeta>();
		for (ImageDraw draw : imageDraws) {
			if (isCheck == null) {
				fileMetas.add(draw.data);
				continue;
			}
			if (draw.checkBox.getSelection() == isCheck) {
				fileMetas.add(draw.data);
			}
		}
		return fileMetas;
	}

	List<String> remove() {
		List<String> fileIdOrNames = new ArrayList<String>();
		List<ImageDraw> disposeImageDraws = new ArrayList<ImageViewer.ImageDraw>();
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection()) {
				fileIdOrNames.add(getId(draw));
				draw.dispose();
				disposeImageDraws.add(draw);
			}
		}
		if (fileIdOrNames.size() == 0) {
			popup("未选择文件");
		}
		imageDraws.removeAll(disposeImageDraws);
		compositeComputeSize();
		return fileIdOrNames;
	}

	void clear() {
		for (ImageDraw draw : imageDraws) {
			draw.dispose();
		}
		imageDraws.clear();
		composite.setSize(0, 0);
		composite.layout();

	}

	public void addImage(String path, FileMeta data) throws MalformedURLException {
		addImage(new URL(path), data);
	}

	public void addImage(URL url, FileMeta data) {
		ImageDraw draw = new ImageDraw(composite, url, data);
		this.imageDraws.add(draw);
		compositeComputeSize();
		this.setFocus();
		draw.update();
	}

	public void addImage(File file, FileMeta fileMeta) {
		try {
			addImage(file.toURI().toURL(), fileMeta);
		} catch (RuntimeException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void asycnAddImage(final File file, final FileMeta fileMeta) {
		try {
			asycnAddImage(file.toURI().toURL(), fileMeta);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void asycnAddImage(URL url, final FileMeta fileMeta) {
		executorService.execute(new Runnable() {

			@Override
			public void run() {
				Display.getDefault().asyncExec(new Runnable() {

					@Override
					public void run() {
						imageViewer.addImage(url, fileMeta);
					}
				});
			}
		});
	}

	List<String> exportImages() {
		List<String> fileNames = new ArrayList<String>();
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection()) {
				fileNames.add(getId(draw));
			}
		}
		return fileNames;
	}

	void checkAll() {
		for (ImageDraw draw : imageDraws) {
			draw.checkBox.setSelection(true);
		}
	}

	void unCheckAll() {
		for (ImageDraw draw : imageDraws) {
			draw.checkBox.setSelection(false);
		}
	}

	// 将图片转换为特定格式 tip
	File swap() throws Throwable {
		/*
		 * List<FileMeta> fileMetas = this.getFileMetaDatas(true); if
		 * (!(fileMetas.size() > 1)) { return null; } List<File> files = new
		 * ArrayList<File>(); for (FileMeta fileMeta : fileMetas) { String fileName =
		 * fileMeta.getEntry(CWXConstants.KEY_FILE_NAME); if (fileName.endsWith(".pdf"))
		 * { throw new Throwable("pdf图片不能再次合并"); } File file =
		 * FileUtil.getFile(fileName); files.add(file); } File target =
		 * PdfUtil.imagesToPdf(files, FileUtil.getBatchPath()); FileMeta fileMeta = new
		 * FileMeta(); fileMeta.getEntries().put(CWXConstants.KEY_FILE_NAME,
		 * target.getName()); fileMeta.setFiletype("pdf");
		 * fileMeta.setFiletype(target.getAbsolutePath());
		 * fileMeta.setGenerateTime(FileUtil.getNowTime()); this.addImage(target,
		 * fileMeta); this.remove();
		 */
		return null;
	}

	void inverse() {
		for (ImageDraw draw : imageDraws) {
			draw.checkBox.setSelection(!draw.checkBox.getSelection());
		}
	}

	void left() {
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection()) {
				// draw.file = left(draw.image);
				draw.redraw();
			}
		}
	}

	void right() {
		for (ImageDraw draw : imageDraws) {
			if (draw.checkBox.getSelection()) {
				// draw.image = right(draw.image);
				draw.redraw();
			}
		}
	}

	@SuppressWarnings("unused")
	private Image right(Image image) {
		if (image != null) {
			ImageData srcData = image.getImageData();
			int bytesPerPixel = srcData.bytesPerLine / srcData.width;
			int destBytesPerLine = srcData.height * bytesPerPixel;
			byte[] newData = new byte[srcData.data.length];
			int width = 0, height = 0;
			for (int srcY = 0; srcY < srcData.height; srcY++) {
				for (int srcX = 0; srcX < srcData.width; srcX++) {
					int destX = 0, destY = 0, destIndex = 0, srcIndex = 0;
					destX = srcData.height - srcY - 1;
					destY = srcX;
					width = srcData.height;
					height = srcData.width;
					destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel);
					srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel);
					System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel);
				}
			}

			ImageData targData = new ImageData(width, height, srcData.depth, srcData.palette, destBytesPerLine,
					newData);
			image = new Image(null, targData);
		}
		return image;
	}

	@SuppressWarnings("unused")
	private Image left(Image image) {
		if (image != null) {
			ImageData srcData = image.getImageData();
			int bytesPerPixel = srcData.bytesPerLine / srcData.width;
			int destBytesPerLine = srcData.height * bytesPerPixel;
			byte[] newData = new byte[srcData.data.length];
			int width = 0, height = 0;
			for (int srcY = 0; srcY < srcData.height; srcY++) {
				for (int srcX = 0; srcX < srcData.width; srcX++) {
					int destX = 0, destY = 0, destIndex = 0, srcIndex = 0;
					destX = srcY;
					destY = srcData.width - srcX - 1;
					width = srcData.height;
					height = srcData.width;
					destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel);
					srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel);
					System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel);
				}
			}

			ImageData targData = new ImageData(width, height, srcData.depth, srcData.palette, destBytesPerLine,
					newData);
			image = new Image(null, targData);
		}
		return image;
	}

	private String getId(ImageDraw draw) {
		if (draw == null || draw.data == null) {
			return null;
		}
		FileMeta fileMeta = draw.data;
		String fileId = fileMeta.getId();
		String fileName = fileMeta.getName();
		return fileId != null ? fileId : fileName;
	}

	void compositeComputeSize() {
		int width = 0;
		Object obj = this.getLayout();
		if (obj instanceof RowLayout) {
			RowData rowData = (RowData) this.getLayoutData();
			width = rowData.width;
		} else if (obj instanceof GridLayout) {
			GridData gridData = (GridData) this.getLayoutData();
			width = gridData.widthHint;
		} else {
			width = this.getSize().x;
		}
		Point point = composite.computeSize(width - verticalBar.getSize().x, SWT.DEFAULT);
		composite.setSize(point.x, point.y + 20);
		composite.layout();
	}

	// 储存宽高
	@Override
	public void setSize(int width, int height) {
		this.width = width;
		this.height = height;
		this.compositeComputeSize();
		super.setSize(width, height);
	}

	@Override
	public void setBounds(int x, int y, int width, int height) {
		this.width = width;
		this.height = height;
		this.compositeComputeSize();
		super.setBounds(x, y, width, height);
	}

	// 计算水平空隙宽度
	public int getVerticalSpace() {
		RowLayout rowLayout = (RowLayout) composite.getLayout();
		return rowLayout.marginLeft + rowLayout.marginRight + rowLayout.spacing * 2;
	}

	// 计算垂直空隙高度
	public int getHorizontalSpace() {
		RowLayout rowLayout = (RowLayout) composite.getLayout();
		return rowLayout.marginTop + rowLayout.marginBottom + rowLayout.spacing * 3;
	}
	

	protected SelectionListener getImageDrawCheckEvent() {
		SelectionListener selectionListener = new SelectionAdapter() {

		};
		return selectionListener;
	}

	protected MouseListener getImageDrawClickEvent() {
		MouseListener mouseListener = new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				if (e.button == 1) {
					ImageDraw imageDraw = (ImageDraw) e.widget;
					if (imageDraw.checkBox != null) {
						imageDraw.checkBox.setSelection(!imageDraw.checkBox.getSelection());
						// 触发check事件
						Event event = new Event();
						event.widget = imageDraw.checkBox;
						event.type = SWT.Selection;
						Display.getCurrent().post(event);
						imageDraw.checkBox.notifyListeners(SWT.Selection, event);
					}
				}
			}

			@Override
			public void mouseDoubleClick(MouseEvent e) {
				if (e.button == 1) {
					try {
						File file = new File(imageDraw.url.toURI());
						Runtime.getRuntime().exec("rundll32 url.dll FileProtocolHandler " + file.getAbsolutePath());
					} catch (URISyntaxException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		};
		return mouseListener;
	}

	/**
	 * 图片容器,放在imageview中,用于包裹图片以及对图片缩放居中
	 */
	public class ImageDraw extends Canvas {

		private URL url;

		private int imageMaxHeight;
		private int imageMaxWidth;

		FileMeta data;

		Button checkBox;

		public ImageDraw(Composite parent, URL url, FileMeta data) {
			super(parent, SWT.BORDER);
			this.url = url;
			imageDraw = this;
			this.data = data;
			imageMaxHeight = computeSize().y * 90 / 100;
			imageMaxWidth = imageMaxHeight;
			// 设置右键菜单
			// this.setMenu(new PopupMenu(this));
			Point point = this.computeSize();
			this.setLayoutData(new RowData(point.x, point.y));
			checkBox = new Button(this, SWT.CHECK);
			checkBox.setBounds(point.x - 20, point.y - 20, 20, 20);
			// this.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
			compositeComputeSize();
			// 显示备注
			/*
			 * if (data != null && data.getEntry("Comments") != null) {
			 * 
			 * }
			 */
			registryEvents();
		}

		/**
		 * 计算每个draw宽高
		 */
		protected Point computeSize() {
			int x = (imageViewer.getSize().x - verticalBar.getSize().x - getVerticalSpace()) / xCount - 1 * xCount;
			int y = (imageViewer.getSize().y - getHorizontalSpace()) / yCount;
			return new Point(x, y);
		}

		protected void painting(PaintEvent arg0) {

			InputStream inputStream = null;
			try {
				inputStream = url.openStream();
				Image image = new Image(null, new ImageData(inputStream));
				image = zoom(image);
				Point point = computeSize();
				int x = (point.x - image.getBounds().width) / 2;
				int y = (point.y - image.getBounds().height) / 2;
				arg0.gc.drawImage(image, x, y);
				arg0.gc.dispose();
				image.dispose();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (inputStream != null) {
					try {
						inputStream.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}

		private void registryEvents() {
			this.addPaintListener(new PaintListener() {

				public void paintControl(PaintEvent arg0) {
					painting(arg0);
				}
			});
			// 注册点击事件
			MouseListener mouseListener = getImageDrawClickEvent();
			this.addMouseListener(mouseListener);

			// 注册选中事件
			SelectionListener selectionListener = getImageDrawCheckEvent();
			this.checkBox.addSelectionListener(selectionListener);
		}

		// 缩放并居中 返回缩放后图片
		protected Image zoom(Image image) {
			Point point = this.computeSize();
			int imageDrawWidth = point.x;

			int width = image.getBounds().width;
			int height = image.getBounds().height;

			// log.debug("加载图片大小 width:" + width + " ,height:" + height);
			if (width > imageMaxWidth || height > imageMaxHeight) {
				double widthRatio = (double) width / (double) imageDrawWidth;
				double heightRatio = (double) height / (double) imageMaxHeight;
				if (widthRatio >= heightRatio) {
					width = imageDrawWidth;
					height = (int) (height / widthRatio);
				} else {
					height = imageMaxHeight;
					width = (int) (width / heightRatio);
				}
				// log.debug("缩放后图片的大小 width:" + width + " ,height:" + height);
				if (width == 0) {
					width = 1;
				}
				if (height == 0) {
					height = 1;
				}
				Image image2 = new Image(null, image.getImageData().scaledTo(width, height));
				image.dispose();
				return image2;
			}
			return image;
		}

		public ImageViewer getImageViewer() {
			return imageViewer;
		}

		public FileMeta getData() {
			return data;
		}

		public void setData(FileMeta data) {
			this.data = data;
		}

	}

	private void popup(final String msg) {

		Display.getDefault().syncExec(new Runnable() {
			@Override
			public void run() {
				Shell s = getShell();
				MessageBox messageBox = new MessageBox(s, SWT.NONE);
				messageBox.setMessage(msg);
				messageBox.setText("提示");
				messageBox.open();
			}
		});
	}

}


3.下载地址
swt-demo.zip

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值