📄 qtree.java
字号:
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 + -