?? titlebar.java
字號:
package org.test.custom.internal;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.test.custom.shell.DesktopForm;
import org.test.custom.shell.InternalShell;
public final class TitleBar extends Canvas {
private static final long UPDATE_DELAY = 25;
private static final int MINIMUM_GRAB_AREA = 2;
private static final String ELLIPSIS = "...";
private static final int LEFT_PADDING = 2;
private static final int RIGHT_PADDING = 2;
private static final int IMAGE_SIZE = 16;
private static final int TOOL_SIZE = 14;
private static final int TOP_PADDING = 1;
private static final int BOTTOM_PADDING = 1;
private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY;
private boolean cancelled;
private volatile long lastUpdate;
private Timer timer = new Timer(true);
private TimerTask timerTask;
private final InternalShell ishell;
private final DesktopForm desktop;
private String text;
private Image image;
private final boolean styleClose, styleMax, styleTool, styleMin;
private final Image closeImage, restoreImage, maximizeImage, minimizeImage;
private final MenuItem restoreItem, closeItem, maximizeItem;
private final Menu defaultPopup;
public TitleBar(InternalShell parent, int style) {
super(parent, checkStyle(style));
this.ishell = parent;
this.desktop = (DesktopForm) ishell.getParent();
// 設置InternalShell的樣式
this.styleClose = (style & SWT.CLOSE) != 0;
this.styleMax = (style & SWT.MAX) != 0;
this.styleMin = (style & SWT.MIN) != 0;
this.styleTool = (style & SWT.TOOL) != 0;
final Display display = getDisplay();
final Shell shell = getShell();
// 得到控件在不同情況下顏色
final Color gradStartColor = display
.getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
final Color gradEndColor = display
.getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
final Color textColor = display
.getSystemColor(SWT.COLOR_TITLE_FOREGROUND);
final Color inactiveGradStartColor = display
.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
final Color inactiveGradEndColor = display
.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
final Color inactiveTextColor = display
.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
GC gc = new GC(this);
int imgHeight = gc.getFontMetrics().getHeight() - 1;
if (imgHeight % 2 == 0)
imgHeight--;
gc.dispose();
// 創建菜單圖形
closeImage = createMenuImage(IMAGE_TYPE_CLOSE, imgHeight);
restoreImage = createMenuImage(IMAGE_TYPE_RESTORE, imgHeight);
maximizeImage = createMenuImage(IMAGE_TYPE_MAXIMIZE, imgHeight);
minimizeImage = createMenuImage(IMAGE_TYPE_MINIMIZE, imgHeight);
// 設置字體
setFont(createTitleFont(getFont(), styleTool));
// 創建菜單欄并且注冊事件偵聽器
defaultPopup = new Menu(this);
restoreItem = new MenuItem(defaultPopup, SWT.PUSH);
restoreItem.setText(LocalizedStrings.POPUP_RESTORE);
restoreItem.setImage(restoreImage);
restoreItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
ishell.setMaximized(false);
}
});
MenuItem minimizeItem = new MenuItem(defaultPopup, SWT.PUSH);
minimizeItem.setText(LocalizedStrings.POPUP_MINIMIZE);
minimizeItem.setEnabled(styleMin);
minimizeItem.setImage(minimizeImage);
/*
* minimizeItem.addListener(SWT.Selection, new Listener() { public void
* handleEvent(Event event) { } });
*/
maximizeItem = new MenuItem(defaultPopup, SWT.PUSH);
maximizeItem.setText(LocalizedStrings.POPUP_MAXIMIZE);
maximizeItem.setImage(maximizeImage);
maximizeItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
ishell.setMaximized(true);
}
});
new MenuItem(defaultPopup, SWT.SEPARATOR);
closeItem = new MenuItem(defaultPopup, SWT.PUSH);
closeItem.setText(LocalizedStrings.POPUP_CLOSE);
closeItem.setEnabled(styleClose);
closeItem.setImage(closeImage);
closeItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
ishell.close();
}
});
// 注冊各種事件偵聽器
addListener(SWT.Paint, new Listener() {
public void handleEvent(Event event) {
Rectangle r = getClientArea();
if (r.width == 0 || r.height == 0)
return;
boolean active = (shell == display.getActiveShell() && ishell
.isActiveShell());
GC gc = event.gc;
gc.setForeground(active ? gradStartColor
: inactiveGradStartColor);
gc.setBackground(active ? gradEndColor : inactiveGradEndColor);
gc.fillGradientRectangle(r.x, r.y, r.width, r.height, false);
int textLeftPadding = LEFT_PADDING;
if (image != null) {
Rectangle imageBounds = image.getBounds();
if (imageBounds.width > IMAGE_SIZE
|| imageBounds.height > IMAGE_SIZE)
gc.drawImage(image, 0, 0, imageBounds.width,
imageBounds.height, LEFT_PADDING, TOP_PADDING,
IMAGE_SIZE, IMAGE_SIZE);
else
gc.drawImage(image, LEFT_PADDING
+ (IMAGE_SIZE - imageBounds.width) / 2,
(r.height - imageBounds.height) / 2);
textLeftPadding += IMAGE_SIZE + LEFT_PADDING;
}
if (text != null && text.length() > 0) {
gc.setForeground(active ? textColor : inactiveTextColor);
String s = text;
int availableWidth = r.width - textLeftPadding
- RIGHT_PADDING;
if (gc.textExtent(s, SWT.DRAW_TRANSPARENT).x > availableWidth) {
int ellipsisWidth = gc.textExtent(ELLIPSIS,
SWT.DRAW_TRANSPARENT).x;
while (s.length() > 0) {
s = s.substring(0, s.length() - 1);
if (gc.textExtent(s, SWT.DRAW_TRANSPARENT).x
+ ellipsisWidth <= availableWidth) {
s += ELLIPSIS;
break;
}
}
}
if (s.length() > 0)
gc.drawString(s, textLeftPadding, (r.height - gc
.getFontMetrics().getHeight()) / 2, true);
}
}
});
addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
if (event.button == 1) {
if (image != null && event.x < LEFT_PADDING + IMAGE_SIZE) {
cancelled = true;
// left-clicking on the image always shows the default
// popup menu
instrumentDefaultPopup(true);
defaultPopup.setLocation(toDisplay(0, getSize().y));
defaultPopup.setVisible(true);
} else {
mouseDownOffsetX = event.x;
mouseDownOffsetY = event.y;
Point p = ishell.getLocation();
snapBackX = p.x;
snapBackY = p.y;
cancelled = false;
}
} else if (event.button == 3) {
if ((event.stateMask & SWT.BUTTON1) != 0
&& snapBackX != Integer.MIN_VALUE
&& snapBackY != Integer.MIN_VALUE) {
ishell.setLocation(snapBackX, snapBackY);
snapBackX = Integer.MIN_VALUE;
snapBackY = Integer.MIN_VALUE;
cancelled = true;
} else {
}
}
}
});
addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
event.doit = false;
Menu m = getMenu();
if (m == null || m.isDisposed()) {
m = defaultPopup;
instrumentDefaultPopup(false);
}
m.setLocation(event.x, event.y);
m.setVisible(true);
}
});
addListener(SWT.MouseDoubleClick, new Listener() {
public void handleEvent(Event event) {
if (event.button == 1) {
if (image != null && event.x < LEFT_PADDING + IMAGE_SIZE) {
if (styleClose)
ishell.close();
} else {
if (styleMax)
ishell.setMaximized(!ishell.getMaximized());
}
cancelled = true;
}
}
});
addListener(SWT.MouseMove, new Listener() {
public void handleEvent(final Event event) {
if (!cancelled && (event.stateMask & SWT.BUTTON1) != 0
&& !ishell.getMaximized()) {
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
long now = System.currentTimeMillis();
if (lastUpdate + UPDATE_DELAY < now) {
performMove(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;
performMove(event);
}
});
}
};
timer.schedule(timerTask, UPDATE_DELAY);
}
}
}
});
addListener(SWT.MouseUp, new Listener() {
public void handleEvent(Event event) {
if (ishell.getMaximized())
return;
if (image == null || event.x >= LEFT_PADDING + IMAGE_SIZE) {
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
if (!cancelled && (event.stateMask & SWT.BUTTON1) != 0) {
performMove(event);
}
}
}
});
final Listener activateListener = new Listener() {
public void handleEvent(Event event) {
redraw();
}
};
final Listener deactivateListener = new Listener() {
public void handleEvent(Event event) {
redraw();
}
};
shell.addListener(SWT.Activate, activateListener);
shell.addListener(SWT.Deactivate, deactivateListener);
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
timer.cancel();
shell.removeListener(SWT.Activate, activateListener);
shell.removeListener(SWT.Deactivate, deactivateListener);
closeImage.dispose();
maximizeImage.dispose();
restoreImage.dispose();
minimizeImage.dispose();
defaultPopup.dispose();
}
});
}
// 重畫窗口,以實現移動的效果。
private void performMove(Event event) {
Point p = ishell.getLocation();
int newX = p.x + event.x - mouseDownOffsetX;
int newY = p.y + event.y - mouseDownOffsetY;
// Make sure that the minimum grab area stays visible
Rectangle deskCA = desktop.getClientArea();
Rectangle bounds = getBounds();
int rightMinGrab = MINIMUM_GRAB_AREA;
if (image != null)
rightMinGrab += LEFT_PADDING + IMAGE_SIZE;
newX = Math.min(Math.max(newX, deskCA.x - bounds.x - bounds.width
+ MINIMUM_GRAB_AREA), deskCA.x - bounds.x + deskCA.width
- rightMinGrab);
newY = Math.min(Math.max(newY, deskCA.y - bounds.y - bounds.height
+ MINIMUM_GRAB_AREA), deskCA.y - bounds.y + deskCA.height
- MINIMUM_GRAB_AREA);
if (newX != p.x || newY != p.y)
ishell.setLocation(newX, newY);
}
public Point computeSize(int wHint, int hHint, boolean changed) {
checkWidget();
if (wHint == SWT.DEFAULT)
wHint = 50;
if (hHint == SWT.DEFAULT) {
GC gc = new GC(this);
hHint = gc.getFontMetrics().getHeight();
hHint = Math.max(hHint, styleTool ? TOOL_SIZE : IMAGE_SIZE);
hHint += TOP_PADDING + BOTTOM_PADDING;
gc.dispose();
}
return new Point(wHint, hHint);
}
private static int checkStyle(int style) {
//int mask = SWT.SHADOW_IN | SWT.FLAT;
//style &= mask;
style = SWT.NO_FOCUS;
return style;
}
public boolean setFocus() {
checkWidget();
return false;
}
public boolean isReparentable() {
checkWidget();
return false;
}
public void setText(String text) {
checkWidget();
this.text = text;
redraw();
}
public String getText() {
return text;
}
public void setImage(Image image) {
checkWidget();
if (styleTool)
return;
this.image = image;
redraw();
}
public Image getImage() {
return image;
}
private Font createTitleFont(Font f, boolean tool) {
FontData[] fds = f.getFontData();
int size = fds.length;
int i = 0;
for (; i < size; i++) {
fds[i].setStyle(fds[i].getStyle() | SWT.BOLD);
if (tool)
fds[i].setHeight((int) (fds[i].getHeight() * 0.9));
}
return new Font(getDisplay(), fds);
}
private void instrumentDefaultPopup(boolean onImage) {
restoreItem.setEnabled(styleMax && ishell.getMaximized());
maximizeItem.setEnabled(styleMax && !ishell.getMaximized());
MenuItem def = null;
if (onImage) {
if (styleClose)
def = closeItem;
} else if (styleMax) {
def = ishell.getMaximized() ? restoreItem : maximizeItem;
}
defaultPopup.setDefaultItem(def);
}
private static final int IMAGE_TYPE_CLOSE = 1;
private static final int IMAGE_TYPE_MAXIMIZE = 2;
private static final int IMAGE_TYPE_RESTORE = 3;
private static final int IMAGE_TYPE_MINIMIZE = 4;
/**
* 創建菜單上的圖形顯示,例如最大化、最小化的按鈕等。
*/
private Image createMenuImage(int type, int height) {
final Point size = new Point(height, height);
final int imgWidth = height + height / 2;
final Color fg = getForeground();
final Color white = getDisplay().getSystemColor(SWT.COLOR_WHITE);
final RGB blackRGB = new RGB(0, 0, 0);
ImageData id = new ImageData(imgWidth, size.y, 1, new PaletteData(
new RGB[] { blackRGB, fg.getRGB() }));
ImageData maskid = new ImageData(imgWidth, size.y, 1, new PaletteData(
new RGB[] { blackRGB, white.getRGB() }));
Image img = new Image(getDisplay(), id);
GC gc = new GC(img);
gc.setForeground(fg);
drawMenuImage(gc, size, type);
gc.dispose();
Image maskimg = new Image(getDisplay(), maskid);
gc = new GC(maskimg);
gc.setForeground(white);
drawMenuImage(gc, size, type);
gc.dispose();
Image transp = new Image(getDisplay(), img.getImageData(), maskimg
.getImageData());
img.dispose();
maskimg.dispose();
return transp;
}
/**
* 實際上執行畫圖操作的私有方法。
*/
private void drawMenuImage(GC gc, Point size, int type) {
switch (type) {
case IMAGE_TYPE_CLOSE:
gc.drawLine(1, 1, size.x - 2, size.y - 2);
gc.drawLine(2, 1, size.x - 2, size.y - 3);
gc.drawLine(1, 2, size.x - 3, size.y - 2);
gc.drawLine(1, size.y - 2, size.x - 2, 1);
gc.drawLine(1, size.y - 3, size.x - 3, 1);
gc.drawLine(2, size.y - 2, size.x - 2, 2);
break;
case IMAGE_TYPE_RESTORE:
gc.drawRectangle(0, 4, size.x - 4, size.y - 6);
gc.drawLine(1, 5, size.x - 5, 5);
gc.drawLine(2, 1, size.x - 2, 1);
gc.drawLine(2, 2, size.x - 2, 2);
gc.drawPoint(2, 3);
gc.drawLine(size.x - 2, 3, size.x - 2, size.y - 5);
gc.drawPoint(size.x - 3, size.y - 5);
break;
case IMAGE_TYPE_MAXIMIZE:
gc.drawRectangle(0, 0, size.x - 2, size.y - 2);
gc.drawLine(1, 1, size.x - 3, 1);
break;
case IMAGE_TYPE_MINIMIZE:
gc.drawLine(1, size.y - 2, size.x - 4, size.y - 2);
gc.drawLine(1, size.y - 3, size.x - 4, size.y - 3);
break;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -