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

📄 richbox.java

📁 java写的qq代码实现qq的部分功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

		caretLine = content.getLineAtOffset(caretOffset);
		if (caretLine < lineCount - 1) {
		    GC gc = getGC();
			int verticalMaximum = contentHelper.getHeightOfLines(gc, 0, lineCount); 
			int pageSize = clientAreaHeight - topMargin - bottomMargin;
			int scrollLines = Math.min(lineCount - caretLine - 1, getFullVisibleLineCount());
			
			scrollLines = Math.max(1, scrollLines);
			caretLine += scrollLines;
			caretOffset = contentHelper.getOffsetAtX(gc, caretLine, columnX);
			if(pageSize > verticalMaximum)
			    showCaret();
			else
			    setVerticalScrollOffset(contentHelper.getHeightOfLines(gc, 0, caretLine), true);
			releaseGC();
		}
		// 显示光标
		showCaret(caretLine);
		columnX = oldColumnX;
	}
	
	/**
	 * 上翻一页,保持光标X位置不变。上翻页将光标减掉view中的全部可见行数。
	 */
	private void doPageUp() {
		int oldColumnX = columnX;
		int caretLine = content.getLineAtOffset(caretOffset);

		// 如果当前光标所在的行大于0,上翻一页
		if (caretLine > 0) {
	        GC gc = getGC();
			int scrollLines = Math.max(1, Math.min(caretLine, getFullVisibleLineCount()));
			int scrollOffset;

			caretLine -= scrollLines;
			caretOffset = contentHelper.getOffsetAtX(gc, caretLine, columnX);
			setVerticalScrollOffset(contentHelper.getHeightOfLines(gc, 0, caretLine), true);
			releaseGC();
		}
		// 显示光标
		showCaret(caretLine);
		columnX = oldColumnX;
	}
	
    /**
     * @return
     * 		返回窗口中完全可见行的行数
     */
    private int getFullVisibleLineCount() {
        GC gc = getGC();
        int fullVisibleBottomLine = getFullVisibleBottomLine(gc);
        int fullVisibleTopLine = topLine;
        if(contentHelper.getHeightOfLines(gc, 0, fullVisibleTopLine) - verticalScrollOffset < 0)
            fullVisibleTopLine++;
        releaseGC();
        int lineCount = fullVisibleBottomLine - fullVisibleTopLine + 1;
        if(lineCount < 0)
            return 0;
        else
            return lineCount;
    }
    
    /**
     * 光标置于最后
     */
    private void doTextEnd() {
        if(caretOffset < content.getCharCount()) {
            caretOffset = content.getCharCount();
            showCaret();
        }
    }
    
    /**
     * 光标置于最开头
     */
    private void doTextStart() {
        if(caretOffset != 0) {
            caretOffset = 0;
            showCaret();
        }
    }
    
    /**
     * 将光标置于行结尾
     */
    private void doLineEnd() {
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineOffset = content.getLineStartOffset(caretLine);
		int lineLength = content.getLine(caretLine).length();
		int lineEndOffset = lineOffset + lineLength;
		if (caretOffset < lineEndOffset) {
			caretOffset = lineEndOffset;
			showCaret();
		}
    }
    
	/**
	 * 将光标置于行开始
	 */
	private void doLineStart() {
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineOffset = content.getLineStartOffset(caretLine);
		if (caretOffset > lineOffset) {
			caretOffset = lineOffset;
			showCaret(caretLine);
		}
	}

	/**
	 *如果存在被选择区,则把光标放置到被选择区结束,否则简单移动
	 * <p>
	 * 
	 * @see #doSimpleCaretRigth
	 */
    private void doCaretRight() {
		if (selectionEnd > selectionStart) {
			int caretLine;

			caretOffset = selectionEnd;
			caretLine = content.getLineAtOffset(caretOffset);
			showCaret(caretLine);
		} else {
			doSimpleCaretRigth();
		}
	}
	
	/**
	 * 往后移动光标一格,如果光标在一行的末尾,则要置光标到下一行的开头,如果后面是个图片,
	 * 要注意移动两个位置
	 */
	private void doSimpleCaretRigth() {
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineOffset = content.getLineStartOffset(caretLine);
		int offsetInLine = caretOffset - lineOffset;
		if (offsetInLine < content.getLine(caretLine).length()) {
			if(content.isImageTag(caretOffset))
			    caretOffset++;
			caretOffset++;
			showCaret();
		} else if (caretLine < content.getLineCount() - 1) {
			caretLine++;
			caretOffset = content.getLineStartOffset(caretLine);
			showCaret(caretLine);
		}
	}
	
	/**
	 * 如果存在被选择区,则把光标放置到被选择区开始,否则简单移动
	 * <p>
	 * 
	 * @see #doSimpleCaretLeft
	 */
	private void doCaretLeft() {
		if (selectionEnd > selectionStart) {
			int caretLine;

			caretOffset = selectionStart;
			caretLine = content.getLineAtOffset(caretOffset);
			showCaret(caretLine);
		} else {
			doSimpleCaretLeft();
		}
	}
	
	/**
	 * 往前移动光标一格,如果光标在一行的开头,则要置光标到上一行的末尾,如果前面是个图片,
	 * 要注意移动两个位置
	 */
	private void doSimpleCaretLeft() {
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineOffset = content.getLineStartOffset(caretLine);
		int offsetInLine = caretOffset - lineOffset;
		if (offsetInLine > 0) {
			caretOffset--;
			if(content.isImageTag(caretOffset - 1))
			    caretOffset--;
			showCaret(caretLine);
		} else if (caretLine > 0) {
			caretLine--;
			lineOffset = content.getLineStartOffset(caretLine);
			int newCaretOffset = lineOffset + content.getLine(caretLine).length();
			if(newCaretOffset == caretOffset)
			    caretOffset--;
			else
			    caretOffset = newCaretOffset;
			if(content.isImageTag(caretOffset - 1))
			    caretOffset--;
			showCaret();
		}
	}
	
	/**
	 * 删除一个用户自定义按键绑定
	 * 
	 * @param key
	 *            a key code defined in SWT.java or a character. Optionally ORd
	 *            with a state mask. Preferred state masks are one or more of
	 *            SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
	 *            modifier platform differences. However, there may be cases
	 *            where using the specific state masks (i.e., SWT.CTRL,
	 *            SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
	 */
	public void removeUserKeyAction(int key) {
	    setUserKeyAction(key, null);
	}
	
	/**
	 * 添加一个用户自定义按键事件
	 * 
	 * @param key
	 * @param action
	 */
	public void setUserKeyAction(int key, Runnable action) {
	    if(action == null)
	        setKeyBinding(key, SWT.NULL);
	    else
	        setKeyBinding(key, CUSTOM_ACTION);
	    
		int keyValue = key & SWT.KEY_MASK;
		int modifierValue = key & SWT.MODIFIER_MASK;
		char keyChar = (char)keyValue;

		if (Character.isLetter(keyChar)) {
			// 添加key的大写形式
			char ch = Character.toUpperCase(keyChar);
			int newKey = ch | modifierValue;
			if (action == null)
			    userActionMap.remove(new Integer(newKey));
			else
			    userActionMap.put(new Integer(newKey), action);
			// 添加key的小写形式
			ch = Character.toLowerCase(keyChar);
			newKey = ch | modifierValue;
			if (action == null)
			    userActionMap.remove(new Integer(newKey));
			else
			    userActionMap.put(new Integer(newKey), action);
		} else {
		    // 不是字符形式的按键则直接添加
			if (action == null)
			    userActionMap.remove(new Integer(key));
			else
			    userActionMap.put(new Integer(key), action);
		}       
	}
	
	/**
	 * 得到用户自定义动作对象
	 * 
	 * @param key
	 * 		按键值
	 * @return
	 * 		Runnable对象
	 */
	public Runnable getUserKeyAction(int key) {
	    return (Runnable)userActionMap.get(new Integer(key));
	}

    /**
	 * 查找和相关按键绑定的动作id
	 * <p>
	 * 
	 * @param key
	 *            a key code defined in SWT.java or a character. Optionally ORd
	 *            with a state mask. Preferred state masks are one or more of
	 *            SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
	 *            modifier platform differences. However, there may be cases
	 *            where using the specific state masks (i.e., SWT.CTRL,
	 *            SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
	 * @return 
	 * 		动作ID,SWT.NULL表示没有动作
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public int getKeyBinding(int key) {
		checkWidget();
		Integer action = (Integer) keyActionMap.get(new Integer(key));
		if (action == null) 
		    return SWT.NULL;
		else
		    return action.intValue();
	}
	
	/**
	 * 添加一个按键绑定
	 * <p>
	 * 
	 * @param key
	 *            a key code defined in SWT.java or a character. Optionally ORd
	 *            with a state mask. Preferred state masks are one or more of
	 *            SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
	 *            modifier platform differences. However, there may be cases
	 *            where using the specific state masks (i.e., SWT.CTRL,
	 *            SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
	 * @param action
	 * 		动作ID
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setKeyBinding(int key, int action) {
		checkWidget();

		int keyValue = key & SWT.KEY_MASK;
		int modifierValue = key & SWT.MODIFIER_MASK;
		char keyChar = (char)keyValue;

		if (Character.isLetter(keyChar)) {
			// 添加key的大写形式
			char ch = Character.toUpperCase(keyChar);
			int newKey = ch | modifierValue;
			if (action == SWT.NULL)
				keyActionMap.remove(new Integer(newKey));
			else
				keyActionMap.put(new Integer(newKey), new Integer(action));
			// 添加key的小写形式
			ch = Character.toLowerCase(keyChar);
			newKey = ch | modifierValue;
			if (action == SWT.NULL)
				keyActionMap.remove(new Integer(newKey));
			else
				keyActionMap.put(new Integer(newKey), new Integer(action));
		} else {
		    // 不是字符形式的按键则直接添加
			if (action == SWT.NULL)
				keyActionMap.remove(new Integer(key));
			else
				keyActionMap.put(new Integer(key), new Integer(action));
		}
	}
	
	/**
	 * 删除一个按键绑定
	 * 
	 * @param key
	 */
	public void removeKeyBinding(int key) {
	    setKeyBinding(key, SWT.NULL);
	}
	
	/**
	 * 添加缺省按键绑定
	 */
	private void createKeyBindings() {
		// 导航按键绑定
		setKeyBinding(SWT.HOME, LINE_START);
		setKeyBinding(SWT.END, LINE_END);
		setKeyBinding(SWT.PAGE_UP, PAGE_UP);
		setKeyBinding(SWT.PAGE_DOWN, PAGE_DOWN);
		setKeyBinding(SWT.HOME | SWT.MOD1, TEXT_START);
		setKeyBinding(SWT.END | SWT.MOD1, TEXT_END);
		setKeyBinding(SWT.PAGE_UP | SWT.MOD1, TEXT_START);
		setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, TEXT_END);
		setKeyBinding(SWT.ARROW_LEFT, COLUMN_LEFT);
		setKeyBinding(SWT.ARROW_RIGHT, COLUMN_RIGHT);
		setKeyBinding(SWT.ARROW_UP, LINE_UP);
		setKeyBinding(SWT.ARROW_DOWN, LINE_DOWN);

		// Selection
		setKeyBinding(SWT.ARROW_UP | SWT.MOD2, SELECT_LINE_UP);
		setKeyBinding(SWT.ARROW_DOWN | SWT.MOD2, SELECT_LINE_DOWN);
		setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, SELECT_COLUMN_LEFT);
		setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, SELECT_COLUMN_RIGHT);
		setKeyBinding('A' | SWT.MOD1, SELECT_ALL);

		// Modification
		setKeyBinding('X' | SWT.MOD1, CUT);
		setKeyBinding('C' | SWT.MOD1, COPY);
		setKeyBinding('V' | SWT.MOD1, PASTE);		
		setKeyBinding(SWT.BS, DELETE_PREVIOUS);
		setKeyBinding(SWT.DEL, DELETE_NEXT);
		setKeyBinding(SWT.CR, NEW_LINE);
	}

    /**
     * @param event
     */
    protected void handleDispose(Event event) {
		removeListener(SWT.Dispose, listener);
		notifyListeners(SWT.Dispose, event);
		event.type = SWT.None;
		
		if (caret != null) {
		    caret.dispose();
		    caret = null;
		}
		if(backXorColor != null)
		    backXorColor.dispose();
		clipboard.dispose();
		beamCursor = null;
    }

    /**
     * @param event
     */
    protected void handlePaint(Event event) {
		// Check if there is work to do
		if (event.height == 0)
			return;
		
        // adjust y position for pixel based scrolling and top margin
		int startLine = contentHelper.getLineAtY(event.gc, verticalScrollOffset);
		int paintYFromTopLine = contentHelper.getHeightOfLines(event.gc, topLine, startLine);
		int topLineOffset = contentHelper.getYOfLine(event.gc, topLine) - verticalScrollOffset;
		int startY = paintYFromTopLine + topLineOffset + topMargin; 
		int renderHeight = event.y + event.height - startY;

		performPaint(event.gc, startLine, startY, renderHeight);
    }
    
    /**
     * 调整光标的位置和大小
     * 
     * @param gc
     * @param y
     */
    private void adjustCaret(GC gc, int y) {
        int delta = topMargin - y;
        if(delta < 0)
            delta = 0;
		caret.setLocation(caret.getLocation().x, y + delta);
		caret.setSize(1, contentHelper.getLineHeight(gc, topLine) - delta);
    }

    /**
     * @param gc
     * @param startLine
     * @param startY
     * @param renderHeight
     */
    private void performPaint(GC gc, int startLine, int startY, int renderHeight) {
		Rectangle clientArea = getClientArea();
		Color background = getBackground();

⌨️ 快捷键说明

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