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

📄 qtree.java

📁 lumaQQ的源文件
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
			gc.setBackground(getBackground());
			gc.fillRectangle(0, paintY, clientArea.width, endY - paintY);
		}
		
		deferredHeight = 0;
	}

	/**
	 * 查找下一个item。对于没有expanded的不考虑
	 * 
	 * @param item
	 * 		当前QItem
	 * @return
	 * 		下一个item,如果已经是最后一个,返回null
	 */
	private QItem nextItem(QItem item) {
		if(item.isExpanded() && item.getItemCount() > 0) {
			return item.getItem(0);
		} else {
			QItem next = null;
			while(next == null && item != null) {
				QItem parentItem = item.getParentItem();
				int index = (parentItem == null) ? indexOf(item) : parentItem.indexOf(item);
				int count = (parentItem == null) ? itemCount : parentItem.getItemCount();
				if(index >= count - 1)
					item = parentItem;
				else
					next = (parentItem == null) ? getItem(index + 1) : parentItem.getItem(index + 1);				
			}
			return next;
		}
	}

	/**
	 * 处理鼠标移动事件
	 * 
	 * @param event
	 */
	protected void handleMouseMove(Event event) {
		QItem item = getItem(event.x, event.y);
		if(item != itemUnderMouse) {
			// 恢复旧item的状态
			if(itemUnderMouse != null) {
				itemUnderMouse.clearHitTestFlag();
				updateItem(itemUnderMouse);
			}
			// 刷新当前item
			if(item != null) {
				int relativeX = event.x - getItemIndent(item);
				int relativeY = event.y - getYAtItem(item) + verticalOffset;
				item.mouseTest(relativeX, relativeY);
			}
			itemUnderMouse = item;	
		} else if(itemUnderMouse != null && enableIconHover){
			// 刷新当前item
			int relativeX = event.x - getItemIndent(itemUnderMouse);
			int relativeY = event.y - getYAtItem(itemUnderMouse) + verticalOffset;
			itemUnderMouse.mouseTest(relativeX, relativeY);
			updateItemIfNeeded(itemUnderMouse);
		}
	}

	/**
	 * 如果item需要重画,则重画他,否则不重画
	 * 
	 * @param item
	 */
	private void updateItemIfNeeded(QItem item) {
		if(item.needRedraw) {
			updateItem(item);
			item.needRedraw = false;
		}
	}

	/**
	 * 处理鼠标双击事件
	 * 
	 * @param event
	 */
	protected void handleMouseDoubleClick(Event event) {
		if(!expandItemOnSingleClick) {
			if((event.stateMask & itemOpenOnButton) != 0)
				if(itemUnderMouse != null && (itemUnderMouse.isMouseOnIcon() || itemUnderMouse.isMouseOnText()))
					itemUnderMouse.setExpanded(!itemUnderMouse.isExpanded());
		}
	}

	/**
	 * 处理鼠标松开事件
	 * 
	 * @param event
	 */
	protected void handleMouseUp(Event event) {
		if(expandItemOnSingleClick) {
			if((event.stateMask & itemOpenOnButton) != 0)
				if(itemUnderMouse != null && (itemUnderMouse.isMouseOnIcon() || itemUnderMouse.isMouseOnText()))
					itemUnderMouse.setExpanded(!itemUnderMouse.isExpanded());
		}
	}

	/**
	 * 处理按键事件
	 * 
	 * @param event
	 */
	protected void handleKeyDown(Event event) {
		int action;
		int key;
		if (event.keyCode != 0) {
			// special key pressed (e.g., F1)
		    key = event.keyCode | event.stateMask;
			action = getKeyBinding(key);
		} else {
			// character key pressed
		    key = event.character | event.stateMask;
			action = getKeyBinding(key);
			if (action == SWT.NULL) {
				// see if we have a control character
				if ((event.stateMask & SWT.CTRL) != 0 && (event.character >= 0)
						&& event.character <= 31) {
					// get the character from the CTRL+char sequence, the control
					// key subtracts 64 from the value of the key that it modifies
					key = (event.character + 64) | event.stateMask;
					action = getKeyBinding(key);
				}
			}
		}
		if (action == SWT.NULL) {		    
		    // 如果没有事件和这个按键绑定,则要检查按键的内容,如果不包含一些
		    // 特殊的按键,则当作普通的输入处理,否则忽略掉	
			// 对于普通的输入,tree的动作是快速查找
			boolean ignore = false;
			if (IS_CARBON) {
				// Ignore acclerator key combinations (we do not want to
				// insert a character in the text in this instance). Do not
				// ignore COMMAND+ALT combinations since that key sequence
				// produces characters on the mac.
				ignore = (event.stateMask ^ SWT.COMMAND) == 0
						|| (event.stateMask ^ (SWT.COMMAND | SWT.SHIFT)) == 0;
			} else {
				// Ignore acclerator key combinations (we do not want to
				// insert a character in the text in this instance). Don't
				// ignore CTRL+ALT combinations since that is the Alt Gr
				// key on some keyboards.
				ignore = (event.stateMask ^ SWT.ALT) == 0
						|| (event.stateMask ^ SWT.CTRL) == 0
						|| (event.stateMask ^ (SWT.ALT | SWT.SHIFT)) == 0
						|| (event.stateMask ^ (SWT.CTRL | SWT.SHIFT)) == 0;
			}
			// ignore anything below SPACE except for line delimiter keys and tab.
			// ignore DEL
			if (!ignore && event.character > 31 && 
					event.character != SWT.DEL && 
					event.character != TAB) {
				doFind(event.character);
			}
		} else if(action == CUSTOM_ACTION) {
			Runnable r = getUserKeyAction(key);
		    if(r != null)
		    	r.run();
		} else {
			invokeAction(key, action);
		}
	}

	/**
	 * 执行某个动作
	 * 
	 * @param action
	 * 		动作id
	 */
	public void invokeAction(int action) {
		if(action != CUSTOM_ACTION)
			invokeAction(0, action);
	}
	
	/**
	 * 执行某个动作
	 * 
	 * @param action
	 * 		动作id
	 */
	public void invokeAction(int key, int action) {
		switch(action) {
			case PAGE_DOWN:
				doPageDown();
				break;
			case PAGE_UP:
				doPageUp();
				break;
			case GO_TOP:
				doGoTop();
				break;
			case GO_BOTTOM:
				doGoBottom();
				break;
			case CUSTOM_ACTION:
				Runnable r = getUserKeyAction(key);
			    if(r != null)
			    	r.run();
			    break;
		}
	}

	/**
	 * 滚动到最底
	 */
	private void doGoBottom() {
		ScrollBar bar = getVerticalBar();
		if(bar != null)
			setVerticalOffset(bar.getMaximum(), true);
	}
	
	/**
	 * 到顶部
	 */
	public void goTop() {
		doGoTop();
	}

	/**
	 * 滚动到最顶
	 */
	private void doGoTop() {
		ScrollBar bar = getVerticalBar();
		if(bar != null)
			setVerticalOffset(0, true);
	}

	/**
	 * 上翻页
	 */
	private void doPageUp() {
		ScrollBar bar = getVerticalBar();
		if(bar != null)
			setVerticalOffset(verticalOffset - clientAreaHeight, true);
	}

	/**
	 * 下翻页
	 */
	private void doPageDown() {
		ScrollBar bar = getVerticalBar();
		if(bar != null)
			setVerticalOffset(verticalOffset + clientAreaHeight, true);
	}

	/**
	 * 查找文本是以character开头(或者拼音以这个开头)的item,显示这个item
	 * 
	 * @param character
	 * 		首字符或拼音首字符
	 */
	private void doFind(char character) {
		collectResult(character);
		if(findResult.size() <= 0)
			return;
		
		revealItem(findResult.get(nextResult++), false);
		if(nextResult >= findResult.size())
			nextResult = 0;
	}

	/**
	 * 收集符合首字符的结果,只在已经展开的范围内搜索
	 * 
	 * @param character
	 * 		首字符或者拼音首字符
	 */
	private void collectResult(char character) {
		if(character == lastChar)
			return;
		if(itemCount <= 0)
			return;
		
		lastChar = character;
		findResult.clear();
		internalCollectResult(items[0]);
		nextResult = 0;
	}

	/**
	 * 递归的搜索符合条件的item
	 * 
	 * @param item
	 * 		查找的item对象 
	 */
	private void internalCollectResult(QItem item) {
		// 检查自己
		if(getFirstPy(item.getText()) == lastChar)
			findResult.add(item);
		// 检查子item
		if(item.isExpanded() && item.getItemCount() > 0)
			internalCollectResult(item.getItem(0));
		// 检查兄弟item
		QItem parentItem = item.getParentItem();
		int index = (parentItem == null) ? indexOf(item) : parentItem.indexOf(item);
		int count = (parentItem == null) ? itemCount : parentItem.getItemCount();
		if(index < count - 1)
			internalCollectResult((parentItem == null) ? getItem(index + 1) : parentItem.getItem(index + 1));
	}

	/**
	 * 处理dispose事件
	 * 
	 * @param event
	 */
	protected void handleDispose(Event event) {
		removeListener(SWT.Dispose, listener);		
		
		if(editor != null)
			editor.dispose();
		
		items = null;
		itemLayouts = null;
		itemImageSizes = null;
		qtreeListeners = null;
		keyActionMap = null;
		userActionMap = null;
		findResult = null;		
	}

	/**
	 * 设置某层的图标大小
	 * 
	 * @param level
	 * 		层号
	 * @param size
	 * 		图片尺寸
	 */
	public void setLevelImageSize(int level, int size) {
		checkWidget();
		checkLevel(level);
		itemImageSizes[level] = size;
		redraw();
	}
	
	/**
	 * 得到某层的图标大小
	 * 
	 * @param level
	 * 		层号
	 * @return
	 * 		图标尺寸
	 */
	public int getLevelImageSize(int level) {
		checkWidget();
		checkLevel(level);
		return itemImageSizes[level];
	}
	
	/**
	 * 设置某层的item布局
	 * 
	 * @param level
	 * 		层号
	 * @param layout
	 * 		布局常量
	 */
	public void setLevelLayout(int level, ItemLayout layout) {
		checkWidget();
		checkLevel(level);
		itemLayouts[level] = layout;
		redraw();
	}
	
	/**
	 * 得到某层的item布局
	 * 
	 * @param level
	 * 		层号
	 * @return
	 * 		布局常量
	 */
	public ItemLayout getLevelLayout(int level) {
		checkWidget();
		checkLevel(level);
		return itemLayouts[level];
	}
	
	/**
	 * 搜索根节点,查询一个item的索引
	 * 
	 * @param item
	 * 		要查询索引的item对象
	 * @return
	 * 		item的索引,如果没找到,返回-1
	 */
	public int indexOf(QItem item) {
		checkWidget();		
		for(int i = 0; i < itemCount; i++) {
			if(items[i] == item)
				return i;
		}
		return -1;
	}
	
	/**
	 * 返回某点下的item对象,坐标都是相对于客户区的值
	 * 
	 * @param x
	 * 		x位置
	 * @param y
	 * 		y位置
	 * @return
	 * 		QItem对象,如果坐标下无item,返回null
	 */
	public QItem getItem(int x, int y) {
		checkWidget();
		QItem item = getItemAtY(y + verticalOffset, null);
		
		if(item == null)
			return null;
		else if(x < getItemIndent(item))
			return null;
		else
			return item;
	}
	
	/**
	 * 得到Item的绝对y坐标,假设其父item都是展开的
	 * 
	 * @param item
	 * 		QItem对象
	 * @return
	 * 		绝对y坐标
	 */
	private int getYAtItem(QItem item) {
		QItem parentItem = item.getParentItem();
		int y = getYInParent(item);	
		while(parentItem != null) {
			y += getItemHeight(parentItem.getLevel());
			y += getYInParent(parentItem);
			parentItem = parentItem.getParentItem();
		}
		return y;
	}
	
	/**
	 * 得到Item的相对坐标,假设其父item都是展开的
	 * 
	 * @param item
	 * 		QItem对象
	 * @return
	 * 		相对坐标
	 */
	int getRelativeYAtItem(QItem item) {
		return getYAtItem(item) - verticalOffset;
	}
	
	/**
	 * 得到Item的缩进值
	 * 
	 * @param item
	 * 		QItem对象
	 * @return
	 * 		水平缩进象素值
	 */
	int getItemIndent(QItem item) {
		return item.getLevel() * levelIndent;
	}

⌨️ 快捷键说明

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