?? desktopform.java
字號:
package org.test.custom.shell;
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.test.custom.internal.DesktopListener;
import org.test.custom.shell.InternalShell;
/**
* DesktopForm負責管理內部Shell。
*/
public class DesktopForm extends Composite {
private static final InternalShell[] EMPTY_INTERNALSHELL_ARRAY = new InternalShell[0];
private static final int FIRST_SHELL_LOCATION = 32;
private static final int SHELL_LOCATION_OFFSET = 16;
private InternalShell activeShell;
private ArrayList desktopListeners = new ArrayList();
private ArrayList visibleShells = new ArrayList();
private int nextShellLocation = FIRST_SHELL_LOCATION;
private boolean showMaximizedTitle;
private boolean autoMaximize = true;
private boolean enableCtrlTab = true;
/**
* DesktopForm類的構造函數; 參數:Composite類和樣式; 功能:調用父類的構造函數、設定背景顏色以及添加listeners;
*
* 注冊了Resize、MouseDown、FocusIn、Traverse和Dispose五個事件的偵聽器;
*/
public DesktopForm(Composite parent, int style) {
super(parent, style);
final Display display = getDisplay();
final Shell shell = getShell();
setBackground(display
.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
Rectangle ca = getClientArea();
Control[] control = getChildren();
int size = control.length;
int i = 0;
for (; i < size; i++) {
if (control[i] instanceof InternalShell)
((InternalShell) control[i]).desktopResized(ca);
}
}
});
final Listener mouseDownFilter = new Listener() {
public void handleEvent(Event event) {
if (!(event.widget instanceof Control))
return;
Control c = (Control) event.widget;
if (c.getShell() != shell)
return;
InternalShell ishell = getInternalShell(c);
if (ishell == null)
return;
activate(ishell);
}
};
final Listener focusInFilter = new Listener() {
public void handleEvent(Event event) {
if (!(event.widget instanceof Control))
return;
Control c = (Control) event.widget;
if (c.getShell() != shell)
return;
InternalShell ishell = getInternalShell(c);
if (ishell == null)
return;
ishell.focusControl = c;
}
};
final Listener traverseFilter = new Listener() {
public void handleEvent(Event event) {
if (!enableCtrlTab)
return;
if (!event.doit)
return;
if ((event.stateMask & SWT.CTRL) == 0)
return;
if (event.detail != SWT.TRAVERSE_TAB_NEXT
&& event.detail != SWT.TRAVERSE_TAB_PREVIOUS)
return;
if (!(event.widget instanceof Control))
return;
Control c = (Control) event.widget;
if (c.getShell() != shell)
return;
InternalShell ishell = getInternalShell(c);
if (ishell == null)
return;
if (event.detail == SWT.TRAVERSE_TAB_NEXT)
activateNextShell();
else
activatePreviousShell();
event.doit = false;
}
};
// 為display添加事件偵聽器,這樣它就能接收任何地方的發生的這些事件
display.addFilter(SWT.MouseDown, mouseDownFilter);
display.addFilter(SWT.FocusIn, focusInFilter);
display.addFilter(SWT.Traverse, traverseFilter);
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
display.removeFilter(SWT.MouseDown, mouseDownFilter);
display.removeFilter(SWT.FocusIn, focusInFilter);
display.removeFilter(SWT.Traverse, traverseFilter);
}
});
}
/**
* DesktopForm類的manage方法; 參數:InternalShell類; 功能:管理主窗口里的Shell;
*/
void manage(final InternalShell ishell) {
Rectangle bounds = getBounds();
if (nextShellLocation > bounds.height - 100
|| nextShellLocation > bounds.width - 100)
nextShellLocation = FIRST_SHELL_LOCATION;
ishell.setLocation(bounds.x + nextShellLocation, bounds.y
+ nextShellLocation);
nextShellLocation += SHELL_LOCATION_OFFSET;
ishell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
visibleShells.remove(ishell);
if (ishell == activeShell) {
activateTopmostVisibleShellExcept(ishell);
if (autoMaximize && !hasVisibleMaximizedShell())
setAllMaximized(false);
}
notifyDesktopListenersDispose(ishell);
}
});
if (ishell.isVisible())
visibleShells.add(ishell);
notifyDesktopListenersCreate(ishell);
}
// 激活除了except以外的InternalShell
private InternalShell activateTopmostVisibleShellExcept(InternalShell except) {
Control[] children = getChildren();
for (int i = 0; i < children.length; i++) {
Control c = children[i];
if (c == except)
continue;
if (c instanceof InternalShell && c.isVisible()) {
InternalShell ishell = (InternalShell) c;
activate(ishell);
return ishell;
}
}
activeShell = null;
notifyDesktopListenersActivate(null);
return null;
}
// 激活ishell窗口
void activate(InternalShell ishell) {
if (ishell == activeShell)
return;
checkWidget();
if ((ishell.getStyle() & SWT.ON_TOP) != 0)
ishell.moveAbove(null);
else {
InternalShell firstRegular = getTopmostRegularShell();
if (firstRegular != null && firstRegular != ishell)
ishell.moveAbove(firstRegular);
}
InternalShell oldActiveShell = activeShell;
activeShell = ishell;
if (oldActiveShell != null)
oldActiveShell.redrawDecorationsAfterActivityChange();
if (activeShell.isVisible())
activeShell.redrawDecorationsAfterActivityChange();
setTabList(new Control[] { activeShell });
activeShell.setFocus();
notifyDesktopListenersActivate(ishell);
}
// 返回最上層的InternalShell
private InternalShell getTopmostRegularShell() {
Control[] control = getChildren();
int size = control.length;
int i;
for (i = 0; i < size; i++) {
if (!(control[i] instanceof InternalShell))
continue;
if ((control[i].getStyle() & SWT.ON_TOP) == 0)
return (InternalShell) control[i];
}
return null;
}
// 返回最底層的InternalShell
private InternalShell getBottommostOnTopShell() {
Control[] ch = getChildren();
for (int i = ch.length - 1; i >= 0; i--) {
Control c = ch[i];
if (!(c instanceof InternalShell))
continue;
if ((c.getStyle() & SWT.ON_TOP) != 0)
return (InternalShell) c;
}
return null;
}
// 改變InternalShell的可見性
void shellVisibilityChanged(InternalShell ishell, boolean visible) {
if (visible) {
if (!visibleShells.contains(ishell)) {
visibleShells.add(ishell);
if (autoMaximize && !ishell.getMaximized()
&& (ishell.getStyle() & SWT.MAX) != 0
&& hasVisibleMaximizedShell())
ishell.setMaximizedWithoutNotification(true);
}
} else {
visibleShells.remove(ishell);
if (ishell == activeShell) {
activateTopmostVisibleShellExcept(ishell);
if (autoMaximize && !hasVisibleMaximizedShell())
setAllMaximized(false);
}
}
}
// 得到InternalShell
private InternalShell getInternalShell(Control c) {
while (c != null && c != DesktopForm.this) {
if (c instanceof InternalShell
&& ((InternalShell) c).getParent() == this)
return (InternalShell) c;
c = c.getParent();
}
return null;
}
/**
* DesktopForm的公共方法;
*
* 返回當前處于活動狀態的內部窗口;
*/
public InternalShell getActiveShell() {
return activeShell;
}
/**
* DesktopForm的公共方法;
*
* 返回DesktopForm中所有可見的窗口;
*/
public InternalShell[] getVisibleShells() {
checkWidget();
return (InternalShell[]) visibleShells
.toArray(EMPTY_INTERNALSHELL_ARRAY);
}
// 設置是否最大化InternalShell時顯示它的菜單欄
public void setShowMaximizedTitle(boolean b) {
checkWidget();
showMaximizedTitle = b;
Rectangle ca = getClientArea();
Control[] control = getChildren();
int size = control.length;
int i = 0;
for (; i < size; i++) {
if (control[i] instanceof InternalShell)
((InternalShell) control[i]).desktopResized(ca);
}
}
/**
* DesktopForm的公共方法
*
* 返回boolean變量,判斷是否顯示標題欄
*/
public boolean getShowMaximizedTitle() {
checkWidget();
return showMaximizedTitle;
}
public void setAutoMaximize(boolean b) {
checkWidget();
autoMaximize = b;
boolean hasMax = false;
Object[] internalShell = visibleShells.toArray();
int size = internalShell.length;
int i;
InternalShell myShell;
for (i = 0; i < size; i++) {
myShell = (InternalShell) internalShell[i];
if (myShell.getMaximized()) {
hasMax = true;
break;
}
}
if (hasMax) {
// Maximize all shells
for (i = 0; i < size; i++) {
myShell = (InternalShell) internalShell[i];
if ((myShell.getStyle() & SWT.MAX) != 0)
myShell.setMaximized(true);
}
}
}
/**
* DesktopForm的公共方法
*
* 返回一個boolean變量,判斷是否允許其自動最大化;
*/
public boolean getAutoMaximize() {
checkWidget();
return autoMaximize;
}
/**
* DesktopForm的公共方法 參數:boolean
*
* 功能:設定enableCtrlTab的值;
*/
public void setEnableCtrlTab(boolean b) {
checkWidget();
this.enableCtrlTab = b;
}
/**
* DesktopForm的公共方法
*
* 返回一個boolean變量,判斷是否允許使用Ctrl+Tab遍歷內部窗口;
*/
public boolean getEnableCtrlTab() {
return enableCtrlTab;
}
// 最大化或返回原始大小
void shellMaximizedOrRestored(InternalShell ishell, boolean maximized) {
setAllMaximized(maximized);
}
// 使所有的InternalShell最大化
private void setAllMaximized(boolean maximized) {
if (autoMaximize) // maximize or restore all shells
{
Control[] control = getChildren();
int size = control.length;
int i;
for (i = 0; i < size; i++) {
if (control[i] instanceof InternalShell) {
InternalShell ishell = (InternalShell) control[i];
if ((ishell.getStyle() & SWT.MAX) != 0)
((InternalShell) control[i])
.setMaximizedWithoutNotification(maximized);
}
}
}
}
// 在遍歷InternalShell時,激發下一個InternalShell
private void activateNextShell() {
if (visibleShells.size() < 2)
return;
InternalShell topReg = getTopmostRegularShell();
InternalShell botTop = getBottommostOnTopShell();
if ((activeShell.getStyle() & SWT.ON_TOP) != 0) {
activeShell.moveBelow(botTop);
if (topReg != null)
activate(topReg);
else
activateTopmostVisibleShellExcept(null);
} else {
activeShell.moveBelow(null);
activateTopmostVisibleShellExcept(null);
}
}
// 激發前一個InternalShell
private void activatePreviousShell() {
if (visibleShells.size() < 2)
return;
InternalShell topReg = getTopmostRegularShell();
InternalShell botTop = getBottommostOnTopShell();
if (activeShell == topReg && botTop != null)
activate(botTop);
else {
Control[] ch = getChildren();
for (int i = ch.length - 1; i >= 0; i--) {
if (ch[i] instanceof InternalShell && ch[i].isVisible()) {
activate((InternalShell) ch[i]);
break;
}
}
}
}
public void addDesktopListener(DesktopListener l) {
desktopListeners.add(l);
}
public void removeDesktopListener(DesktopListener l) {
desktopListeners.remove(l);
}
/**
* DesktopForm的私有方法;
*
* 產生InternalShell被創建的事件通知
*/
private void notifyDesktopListenersCreate(InternalShell ishell) {
Event event = new Event();
event.widget = ishell;
Object[] listener = desktopListeners.toArray();
int size = listener.length;
int i = 0;
DesktopListener mylistener;
for (; i < size; i++) {
mylistener = (DesktopListener) listener[i];
mylistener.shellCreated(event);
}
}
// 產生InternalShell被銷毀的事件通知
private void notifyDesktopListenersDispose(InternalShell ishell) {
Event event = new Event();
event.widget = ishell;
Object[] listener = desktopListeners.toArray();
int size = listener.length;
int i = 0;
DesktopListener mylistener;
for (; i < size; i++) {
mylistener = (DesktopListener) listener[i];
mylistener.shellDisposed(event);
}
}
// InternalShell被激活的事件
private void notifyDesktopListenersActivate(InternalShell ishell) {
Event event = new Event();
event.widget = ishell;
Object[] listener = desktopListeners.toArray();
int size = listener.length;
int i = 0;
DesktopListener mylistener;
for (; i < size; i++) {
mylistener = (DesktopListener) listener[i];
mylistener.shellActivated(event);
}
}
// 是否含有最大化的InternalShell
private boolean hasVisibleMaximizedShell() {
Object[] internalShell = visibleShells.toArray();
int size = internalShell.length;
int i;
InternalShell myShell;
for (i = 0; i < size; i++) {
myShell = (InternalShell) internalShell[i];
if (myShell.getMaximized())
return true;
}
return false;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -