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

📄 desktopform.java

📁 Eclipse编程技术与实例一书的附CD-ROM光盘
💻 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 + -