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

📄 richbox.java

📁 java写的qq代码实现qq的部分功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            y = topMargin;
        } else if(y < clientAreaHeight - bottomMargin && y + h > clientAreaHeight - bottomMargin) {
            h = clientAreaHeight - bottomMargin - y;
        } else if(y < topMargin || y >= clientAreaHeight - bottomMargin && clientAreaHeight != 0) {
            caret.setVisible(false);
            return;
        }
        caret.setVisible(true);
        caret.setLocation(newCaretX + leftMargin , y);
        caret.setSize(1, h);
        columnX = newCaretX;
    }

    /**
     * 计算最顶行索引
     */
    void calculateTopLine() {
        topLine = contentHelper.getLineAtY(getGC(), verticalScrollOffset);
        releaseGC();
    }

    /**
     * @param event
     */
    protected void handleTraverse(Event event) {
		switch (event.detail) {
			case SWT.TRAVERSE_ESCAPE:
			case SWT.TRAVERSE_PAGE_NEXT:
			case SWT.TRAVERSE_PAGE_PREVIOUS:
				event.doit = true;
				break;
			case SWT.TRAVERSE_RETURN:
			case SWT.TRAVERSE_TAB_NEXT:
			case SWT.TRAVERSE_TAB_PREVIOUS:
				if (readonly || (event.stateMask & SWT.MODIFIER_MASK) != 0) {
					event.doit = true;
				}
				break;
		}
    }
    
    /**
     * @return
     * 		被选择的内容
     */
    public String getSelection() {
        return content.getText(selectionStart, selectionEnd);
    }
    
    /**
     * @return
     * 		true表示有选择的区域
     */
    public boolean hasSelection() {
        return selectionEnd != selectionStart;
    }

    /**
     * @param event
     */
    protected void handleResize(Event event) {
		int oldHeight = clientAreaHeight;
		int oldWidth = clientAreaWidth;

		Rectangle clientArea = getClientArea();
		clientAreaHeight = clientArea.height;
		clientAreaWidth = clientArea.width;
		
		// rewrap and redraw
		if(oldWidth != clientAreaWidth) {
		    content.wrap(clientAreaWidth - leftMargin - rightMargin);
		    redraw();
		}
		// refresh scroll bar
		setScrollBars();
		// reset caret
		if (oldHeight != clientAreaHeight)
			calculateTopLine();		
		if(clientAreaHeight > 0 && clientAreaWidth - leftMargin - rightMargin > 0)
		    showCaret();
    }

    /**
     * @param event
     */
    protected void handleMouseMove(Event event) {
		if ((event.stateMask & SWT.BUTTON1) == 0)
			return;
		
		event.y -= topMargin;
		event.x -= leftMargin;
		doMouseLocationChange(event.x, event.y, true);
		doAutoScroll(event);
    }
    
	/**
	 * 如果鼠标出了客户区,自动滚动
	 */
	private void doAutoScroll(Event event) {
		Rectangle area = getClientArea();

		if (event.y > area.height)
			doAutoScroll(SWT.DOWN);
		else if (event.y < 0)
			doAutoScroll(SWT.UP);
		else
			endAutoScroll();
	}
	
	/**
	 * 结束自动滚动
	 */
	private void endAutoScroll() {
		autoScrollDirection = SWT.NULL;
	}

	/**
	 * 开始自动滚动
	 * <p>
	 * 
	 * @param direction
	 *            SWT.UP, SWT.DOWN
	 */
	private void doAutoScroll(int direction) {
		// 方向相同则不用管
		if (autoScrollDirection == direction)
			return;

		// 方向不合法则返回
		if (direction != SWT.UP && direction != SWT.DOWN)     
		    return;
		// 开始滚动
		autoScrollDirection = direction;
		getDisplay().timerExec(AUTO_SCROLL_INTERVAL, autoScrollTimer);
	}

	/**
	 * 往上选择一行
	 */
	private void doLineUp() {
		int oldColumnX;
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineStartOffset = content.getLineStartOffset(caretLine);
		
		// 保存当前光标X偏移
		oldColumnX = columnX;
		
		if (caretLine > 0)
			caretLine = doSimpleLineUp();
		
		// 显示光标
		showCaret(caretLine);
		// save the original horizontal caret position
		columnX = oldColumnX;
	}
	
	/**
	 * 显示光标,这个方法会修改光标X位置
	 */
	private void showCaret() {
		int caretLine = content.getLineAtOffset(caretOffset);
		showCaret(caretLine);		    
	}
	
	/**
	 * 把光标置于caretLine行,并且让光标可见,也就是要让caretLine行可见
	 * 这个方法会修改光标X位置
	 */
	private void showCaret(int caretLine) {
		boolean scrolled = showLine(caretLine);
		if (scrolled == false)
			setCaretLocation();
	}
	
	/**
	 * 光标所在行减1,保持光标水平位置基本不变
	 * 
	 * @return
	 * 		光标所在行号
	 */
	private int doSimpleLineUp() {
		int caretLine = content.getLineAtOffset(caretOffset);
		if (caretLine > 0) {
			caretLine--;
			caretOffset = contentHelper.getOffsetAtX(getGC(), caretLine, columnX);
			releaseGC();
		}
		return caretLine;
	}
	
	/**
	 * 使指定的行处于view中,如果这一行当前不在view中,则需要滚动
	 * <p>
	 * 
	 * @param line
	 * 		需要显示的行的行号
	 * @return 
	 * 		true表示经过了滚动,false表示没有
	 */
	private boolean showLine(int line) {
		boolean scrolled = false;

		GC gc = getGC();
		if (line <= topLine) {
			scrolled = setVerticalScrollOffset(contentHelper.getHeightOfLines(gc, 0, line), true);
		} else if (line > getFullVisibleBottomLine(gc)) {
			scrolled = setVerticalScrollOffset(contentHelper.getHeightOfLines(gc, 0, line + 1) - clientAreaHeight + topMargin + bottomMargin, true);
		}
		releaseGC();
		return scrolled;
	}

	/**
     * @return
     * 		得到view中的最后一个全部可见行的行号
     */
    private int getFullVisibleBottomLine(GC gc) {
        int y = clientAreaHeight - topMargin - bottomMargin + verticalScrollOffset;
        int line = contentHelper.getLineAtY(gc, y);
        if(contentHelper.getHeightOfLines(gc, 0, line + 1) > y)
            line--;
        return line;
    }
    
    /**
     * @param gc
     * 		GC
     * @return
     * 		得到view中可见的最后一行的行号,不需要全部可见
     */
    private int getBottomLine(GC gc) {
        int y = clientAreaHeight - topMargin - bottomMargin + verticalScrollOffset;
        return contentHelper.getLineAtY(gc, y);
    }

    /**
     * 往下选择一行
	 */
	private void doLineDown() {
		int oldColumnX;
		int caretLine;
		int lineStartOffset;

		caretLine = content.getLineAtOffset(caretOffset);
		lineStartOffset = content.getLineStartOffset(caretLine);
		// 保存光标X参照点以便移动后恢复
		oldColumnX = columnX;
		
		if (caretLine < content.getLineCount() - 1)
			caretLine = doSimpleLineDown();

		// 显示光标
		showCaret(caretLine);
		// save the original horizontal caret position
		columnX = oldColumnX;
	}	

	/**
	 * 光标所在行加1,保持光标水平位置基本不变
	 * 
	 * @return index of the new line relative to the first line in the document
	 */
	private int doSimpleLineDown() {
		int caretLine = content.getLineAtOffset(caretOffset);
		if (caretLine < content.getLineCount() - 1) {
			caretLine++;
			caretOffset = contentHelper.getOffsetAtX(getGC(), caretLine, columnX);
			releaseGC();
		}
		return caretLine;
	}
	
    /**
     * @param event
     */
    protected void handleMouseDoubleClick(Event event) {
		if (event.button != 1 || doubleClickEnabled == false)
			return;
		
		// 得到应该被选择的区域
		int caretLine = content.getLineAtOffset(caretOffset);
		int lineStartOffset = content.getLineStartOffset(caretLine);
		int nextLineStartOffset = content.getLineStartOffset(caretLine + 1);
		
		// 重置选择区
		resetSelection(lineStartOffset, nextLineStartOffset);
	
		// 重置光标
		caretOffset = lineStartOffset;
		setCaretLocation();
    }
    
    /**
     * 将被选择区域置为指定的值,我们需要重画旧的选择区,再画新的选择区
     * 
     * @param start
     * @param end
     */
    private void resetSelection(int start, int end) {
		int oldStart = selectionStart;
		int oldEnd = selectionEnd;		
		resetSelection();
		redrawRange(oldStart, oldEnd);
		
		// 画新的选择区		
		selectionStart = start;
		selectionEnd = end;
		redrawRange(selectionStart, selectionEnd);
		if(!IS_WIN32 && selectionEnd != selectionStart)
		    setClipboardContent(selectionStart, selectionEnd - selectionStart);
    }
    
    /**
     * 重画start和end之间的字符,不包括end
     * 
     * @param start
     * @param end
     */
    private void redrawRange(int start, int end) {
        if(end <= start)
            return;
        
        GC gc = getGC();
        int startLine = content.getLineAtOffset(start);
        int endLine = content.getLineAtOffset(end - 1);
        int bottomLine = getBottomLine(gc);
        if(endLine < topLine || startLine > bottomLine)
            return;
        
        // 让开始行和结束行出现在view中
        while(startLine < topLine)
            startLine++;
        while(endLine > bottomLine)
            endLine--;
        
        int y = contentHelper.getHeightOfLines(gc, 0, startLine) - verticalScrollOffset + topMargin;
        int h = contentHelper.getHeightOfLines(gc, startLine, endLine + 1);
        releaseGC();
        redraw(leftMargin, y, clientAreaWidth - leftMargin - rightMargin, h, true);
    }
    
	/**
	 * Resets the selection.
	 */
	private void resetSelection() {
		selectionStart = selectionEnd = caretOffset;
	}

    /**
     * @param event
     */
    protected void handleMouseUp(Event event) {
        endAutoScroll();
        
		if ((event.stateMask & SWT.BUTTON3) != 0 && enableContextMenu) {
		    contextMenu.setLocation(toDisplay(event.x, event.y));
			contextMenu.setVisible(true);
		}
    }

    /**
     * @param event
     */
    protected void handleMouseDown(Event event) {
        if(!IS_WIN32 && event.button == 2) {
            paste();
            return;
        }
		if ((event.button != 1)
				|| (IS_CARBON && (event.stateMask & SWT.MOD4) != 0)) {
			return;
		}
		event.x -= leftMargin;
		event.y -= topMargin;
		if(event.x < 0 || event.y < 0)
		    return;
		doMouseLocationChange(event.x, event.y, false);
    }
    
    /**
     * 清除选择区
     */
    private void clearSelection() {
        int oldStart = selectionStart;
        int oldEnd = selectionEnd;
        resetSelection();
        redrawRange(oldStart, oldEnd);
    }

    /**
     * @param x
     * @param y
     * @param move
     * 		true表示鼠标在移动中
     */
    private void doMouseLocationChange(int x, int y, boolean move) {
        GC gc = getGC();
        int lineIndex = contentHelper.getLineAtY(gc, y + verticalScrollOffset);
		caretOffset = contentHelper.getOffsetAtX(gc, lineIndex, x);
		setCaretLocation();
        releaseGC();
        
        if(move) {
            // 判断谁先谁后,谁应该是start,谁是end
            if(caretOffset >= selectionAnchor)
                resetSelection(selectionAnchor, caretOffset);
            else
                resetSelection(caretOffset, selectionAnchor);
        } else {
            selectionAnchor = caretOffset;
            clearSelection();
        }
    }

    /**
     * @param event
     */
    protected void handleKeyDown(Event event) {
		Event verifyEvent = new Event();

		verifyEvent.character = event.character;
		verifyEvent.keyCode = event.keyCode;
		verifyEvent.stateMask = event.stateMask;
		verifyEvent.doit = true;
		notifyListeners(VerifyKey, verifyEvent);
		if (verifyEvent.doit == true) {
			handleKey(event);
		}
    }

    /**
     * @param event
     */
    protected void handleKey(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;

⌨️ 快捷键说明

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