⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sizeborder.java

📁 Eclipse 编程技术与实例,讲解了Eclipse编辑器的使用方法
💻 JAVA
字号:
package org.test.custom.form;

import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.Listener;
import org.eclipse.swt.widgets.Shell;

public class SizeBorder extends Canvas {
	private static final long UPDATE_DELAY = 25;

	private static final int AREA_NONE = 0;

	private static final int AREA_N = 1;

	private static final int AREA_S = 2;

	private static final int AREA_E = 4;

	private static final int AREA_W = 8;

	private static final int AREA_NW = 9;

	private static final int AREA_NE = 5;

	private static final int AREA_SE = 6;

	private static final int AREA_SW = 10;

	private Rectangle snapBack;

	private boolean cancelled = true;

	private volatile long lastUpdate;

	private Timer timer = new Timer(true);

	private TimerTask timerTask;

	private Composite resizableParent;

	private Point minSize, mouseDownOffset;

	private int borderWidth = 4, cornerSize = 16;

	private Display display;

	private Cursor cursor, cursorNWSE, cursorNESW, cursorWE, cursorNS;

	private int currentArea;

	public SizeBorder(Composite parent, int style) {
		this(parent, parent.getShell(), style);
	}

	public SizeBorder(Composite parent, final Composite resizableParent,
			int style) {
		super(parent, checkStyle(style));
		this.resizableParent = resizableParent;
		this.display = getDisplay();

		cursorNWSE = new Cursor(getDisplay(), SWT.CURSOR_SIZENWSE);
		cursorNESW = new Cursor(getDisplay(), SWT.CURSOR_SIZENESW);
		cursorWE = new Cursor(getDisplay(), SWT.CURSOR_SIZEWE);
		cursorNS = new Cursor(getDisplay(), SWT.CURSOR_SIZENS);

		// 销毁创建的Cursor控件
		addListener(SWT.Dispose, new Listener() {
			public void handleEvent(Event e) {
				cursorNWSE.dispose();
				cursorNESW.dispose();
				cursorWE.dispose();
				cursorNS.dispose();
			}
		});

		// 没有设置SWT.BORDER情况下的样式
		if ((style & SWT.BORDER) != 0) {
			final Color highlightShadowColor = display
					.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
			final Color lightShadowColor = display
					.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
			final Color normalShadowColor = display
					.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
			final Color darkShadowColor = display
					.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW);

			addListener(SWT.Paint, new Listener() {
				public void handleEvent(Event event) {
					Rectangle r = getClientArea();
					if (r.width == 0 || r.height == 0)
						return;
					drawBevelRect(event.gc, r.x, r.y, r.width - 1,
							r.height - 1, lightShadowColor, darkShadowColor);
					drawBevelRect(event.gc, r.x + 1, r.y + 1, r.width - 3,
							r.height - 3, highlightShadowColor,
							normalShadowColor);
				}
			});
		}

		addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event event) {
				// 处理右键和左键的事件
				if (event.button == 1) {
					currentArea = areaAtPoint(event.x, event.y);
					if (currentArea == AREA_NONE)
						return;
					if (resizableParent instanceof Shell)
						mouseDownOffset = toDisplay(event.x, event.y);
					else
						mouseDownOffset = display.map(SizeBorder.this,
								resizableParent.getParent(), event.x, event.y);
					snapBack = resizableParent.getBounds();
					cancelled = false;
				} else if (event.button == 3
						&& (event.stateMask & SWT.BUTTON1) != 0) {
					if (snapBack != null) {
						resizableParent.setBounds(snapBack);
						snapBack = null;
						cancelled = true;
					}
				}
			}
		});

		// 注册光标移动的事件侦听器
		addListener(SWT.MouseMove, new Listener() {
			public void handleEvent(final Event event) {
				if ((event.stateMask & SWT.BUTTON1) == 0)
					updateCursor(areaAtPoint(event.x, event.y));

				if (!cancelled && (event.stateMask & SWT.BUTTON1) != 0) {
					if (timerTask != null) {
						timerTask.cancel();
						timerTask = null;
					}
					long now = System.currentTimeMillis();
					if (lastUpdate + UPDATE_DELAY < now) {
						performResize(event);
						lastUpdate = now;
					} else {
						timerTask = new TimerTask() {
							public void run() {
								final TimerTask executingTask = this;
								event.display.asyncExec(new Runnable() {
									public void run() {
										if (executingTask != timerTask)
											return;
										performResize(event);
									}
								});
							}
						};
						timer.schedule(timerTask, UPDATE_DELAY);
					}
				}
			}
		});

		addListener(SWT.MouseUp, new Listener() {
			public void handleEvent(Event event) {
				if (timerTask != null) {
					timerTask.cancel();
					timerTask = null;
				}
				if (!cancelled && (event.stateMask & SWT.BUTTON1) != 0) {
					performResize(event);
				}
			}
		});

		addListener(SWT.Show, new Listener() {
			public void handleEvent(Event event) {
				Point p = toControl(display.getCursorLocation());
				updateCursor(areaAtPoint(p.x, p.y));
			}
		});

		addListener(SWT.Dispose, new Listener() {
			public void handleEvent(Event event) {
				timer.cancel();
			}
		});
	}

	private static int checkStyle(int style) {
		//int mask = SWT.NONE;
		//style &= mask;
		style = SWT.NO_FOCUS;
		return style;
	}

	// 执行重画窗口的动作
	private void performResize(Event event) {
		// 首先确认在父类窗口之中
		Rectangle ca;
		if (resizableParent instanceof Shell)
			ca = getDisplay().getClientArea();
		else
			ca = getDisplay().map(resizableParent.getParent(), null,
					resizableParent.getParent().getClientArea());
		Point caOffset = toControl(ca.x, ca.y);
		event.x = Math.max(Math.min(event.x, caOffset.x + ca.width - 1),
				caOffset.x);
		event.y = Math.max(Math.min(event.y, caOffset.y + ca.height - 1),
				caOffset.y);

		// 计算相对于初始鼠标位置的移动
		Point movement = (resizableParent instanceof Shell) ? toDisplay(
				event.x, event.y) : display.map(this, resizableParent
				.getParent(), event.x, event.y);
		movement.x -= mouseDownOffset.x;
		movement.y -= mouseDownOffset.y;

		// 计算窗口新的大小和位置
		int newW = snapBack.width, newH = snapBack.height, newX = snapBack.x, newY = snapBack.y;
		if ((currentArea & AREA_E) != 0)
			newW += movement.x;
		else if ((currentArea & AREA_W) != 0) {
			newW -= movement.x;
			newX += snapBack.width - newW;
		}
		if ((currentArea & AREA_S) != 0)
			newH += movement.y;
		else if ((currentArea & AREA_N) != 0) {
			newH -= movement.y;
			newY += snapBack.height - newH;
		}

		// 限定其大小
		int minW, minH;
		if (minSize != null) {
			minW = minSize.x;
			minH = minSize.y;
		} else {
			minW = 0;
			minH = 0;
		}
		int maxX = snapBack.x + snapBack.width - minW;
		int maxY = snapBack.y + snapBack.height - minH;

		newW = Math.max(minW, newW);
		newH = Math.max(minH, newH);
		newX = Math.min(maxX, newX);
		newY = Math.min(maxY, newY);

		resizableParent.setBounds(newX, newY, newW, newH);
	}

	// 更改光标的位置
	private void updateCursor(int area) {
		Cursor c = null;
		switch (area) {
		case AREA_N:
		case AREA_S:
			c = cursorNS;
			break;
		case AREA_W:
		case AREA_E:
			c = cursorWE;
			break;
		case AREA_NW:
		case AREA_SE:
			c = cursorNWSE;
			break;
		case AREA_NE:
		case AREA_SW:
			c = cursorNESW;
			break;
		}
		if (cursor == c)
			return;
		cursor = c;
		setCursor(c);
	}

	// 判断内部窗口的范围
	private int areaAtPoint(int x, int y) {
		Point size = getSize();
		if (x < borderWidth) // left edge
		{
			if (y < cornerSize)
				return AREA_NW;
			else if (y >= size.y - cornerSize)
				return AREA_SW;
			else
				return AREA_W;
		} else if (x >= size.x - borderWidth) // right edge
		{
			if (y >= size.y - cornerSize)
				return AREA_SE;
			else if (y < cornerSize)
				return AREA_NE;
			else
				return AREA_E;
		} else if (y < borderWidth) // top edge
		{
			if (x < cornerSize)
				return AREA_NW;
			else if (x >= size.x - cornerSize)
				return AREA_NE;
			else
				return AREA_N;
		} else if (y >= size.y - borderWidth) // bottom edge
		{
			if (x >= size.x - cornerSize)
				return AREA_SE;
			else if (x < cornerSize)
				return AREA_SW;
			else
				return AREA_S;
		} else
			return AREA_NONE;
	}

	public Point computeSize(int wHint, int hHint, boolean changed) {
		checkWidget();
		if (wHint == SWT.DEFAULT)
			wHint = 0;
		if (hHint == SWT.DEFAULT)
			hHint = 0;
		return new Point(wHint, hHint);
	}

	public boolean setFocus() {
		checkWidget();
		return false;
	}

	public boolean isReparentable() {
		checkWidget();
		return false;
	}

	// 设置窗口允许的最小尺寸
	public void setMinimumShellSize(Point p) {
		checkWidget();
		this.minSize = p;
	}

	public void setMinimumShellSize(int width, int height) {
		checkWidget();
		this.minSize = new Point(width, height);
	}

	// 设置边框的大小
	public void setBorderWidth(int width) {
		checkWidget();
		borderWidth = width;
		Point p = toControl(display.getCursorLocation());
		updateCursor(areaAtPoint(p.x, p.y));
	}

	public void setCornerSize(int size) {
		checkWidget();
		cornerSize = size;
		Point p = toControl(display.getCursorLocation());
		updateCursor(areaAtPoint(p.x, p.y));
	}

	// 画出矩形
	private static void drawBevelRect(GC gc, int x, int y, int w, int h,
			Color topleft, Color bottomright) {
		gc.setForeground(bottomright);
		gc.drawLine(x + w, y, x + w, y + h);
		gc.drawLine(x, y + h, x + w, y + h);

		gc.setForeground(topleft);
		gc.drawLine(x, y, x + w - 1, y);
		gc.drawLine(x, y, x, y + h - 1);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -