?? sizeborder.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 + -