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

📄 chatbox.java

📁 用java实现的
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
					lineCache.delete(caretChar, caretChar + 1);
				else 
					nextLine.delete(0, 1);
			}
			
			// 删除他,他的字符追加到当前行
			lineBufs.remove(caretLine + 1);
			lineCache.append(nextLine.getChars());
			lineCache.appendSmiley(nextLine.getSmiley());
			// 得到下一行的hard属性
			lineCache.hardLine = nextLine.hardLine;
			// 调整行,注意我们要减1,因为我们上面删了一行
			i = adjustLine(gc, lineCache) - 1;
			
			lines += i;
			// 调整视口
			if(i < 0)
				viewEndLine = getEndLine(viewBeginLine);
			// 调整卷滚条
			adjustVerticalBar();
			gc.dispose();
		}
		
		setCaretLine(caretLine);
		redraw();
	}

	// 处理下方向键
	private void handleDownKey() {
		if(caretLine == lines - 1) return;
		else {
			caretLine++;
			if(caretLine > viewEndLine) {					
				viewEndLine++;
				viewBeginLine = getBeginLine(viewEndLine);
				adjustVerticalBar();
			}
		}
		clearSelected();
		GC gc = new GC(this);
		int w = caret.getLocation().x - margin;
		caretChar = ((LineCache)lineBufs.get(caretLine)).getBeginCharIndexLessThanWidth(gc, w);
		gc.dispose();
		redraw();
	}

	// 处理End按键
	private void handleEndKey(KeyEvent e) {
		// 如果按了CTRL,则回到最开头
		if((e.stateMask & SWT.CTRL) != 0) {
			viewEndLine = lines - 1;
			viewBeginLine = getBeginLine(viewEndLine);
			// 设置光标参数
			setCaretLine(viewEndLine);
			caretChar = ((LineCache)lineBufs.get(caretLine)).size();
			// 调整卷滚条
			adjustVerticalBar();
			// 重画
			redraw();
		} else 
			caretChar = ((LineCache)lineBufs.get(caretLine)).size();			
		clearSelected();

		redraw();
	}

	// 处理回车
	private void handleEnterKey() {
		LineCache line = (LineCache)lineBufs.get(caretLine);
		// 如果有选择部分,则先删除选择部分
		if(selected) {
			handleDeleteKey();
		}
		GC gc = new GC(this);
		// 得到当前行,删除enter发生的位置之后的所有字符,做为下一行
		//     新行将具有和当前行一样的hard属性,同时当前行的hardline属性
		//     被置为true
		LineCache newLine = new LineCache();
		newLine.append(line.delete(caretChar));		
		newLine.appendSmiley(line.exceedSmiley);
		newLine.hardLine = line.hardLine;
		line.hardLine = true;
		// 添加新行
		lineBufs.add(caretLine + 1, newLine);
		// 如果是软分行,要接着调整后面的行,注意外面把i初始化为1,因为如果newline的hardline为
		//     false,那么if不会被执行,新行就是newLine
		int i = 1;
		if(newLine.size() > 0 && !newLine.hardLine) {
			// 得到新行后面一行并删除
			LineCache nextLine = (LineCache)lineBufs.get(caretLine + 2);
			lineBufs.remove(caretLine + 2);
			// 把删除的这行的内容添加到新行
			newLine.append(nextLine.getChars());
			newLine.appendSmiley(nextLine.getSmiley());
			// 删除行的hard属性赋予新行
			newLine.hardLine = nextLine.hardLine;
			// 调整新行
			i = adjustLine(gc, newLine);
		}
		// 调整总行数
		lines += i;
		// 改变光标位置
		caretLine++;
		caretChar = 0;
		// 调整视口
		if(caretLine > viewEndLine) {
			viewEndLine++;
			viewBeginLine = getBeginLine(viewEndLine);
		} else if(i > 0)
			viewEndLine = getEndLine(viewBeginLine);
		
		// 调整垂直卷滚条
		adjustVerticalBar();

		gc.dispose();
		redraw();
	}

	// 处理Home按键
	private void handleHomeKey(KeyEvent e) {
		// 如果按了CTRL,则回到最开头
		if((e.stateMask & SWT.CTRL) != 0){
			// 调整开始行和结束行
			viewBeginLine = 0;
			viewEndLine = getEndLine(viewBeginLine);
			// 调整光标参数
			caretChar = 0;
			setCaretLine(0);
			// 调整卷滚条
			adjustVerticalBar();
			// 重画
			redraw();
		} else
			caretChar = 0;
		clearSelected();

		redraw();
	}

	// 处理左方向键
	private void handleLeftKey() {
		if(caretChar == 0) {
			if(caretLine == 0) return;
			else {
				caretLine--;
				caretChar = ((LineCache)lineBufs.get(caretLine)).size();
				if(caretLine < viewBeginLine) {
					viewBeginLine--;
					viewEndLine = getEndLine(viewBeginLine);
					adjustVerticalBar();
				}					
			}
		} else 
			caretChar--;
		clearSelected();

		redraw();
	}

	// 处理右方向键
	private void handleRightKey() {
		int size = ((LineCache)lineBufs.get(caretLine)).size();
		if(caretChar >= size) {
			if(caretLine == lines - 1) return;
			else  {
				caretLine++;
				caretChar = 0;
				if(caretLine > viewEndLine) {
					viewEndLine++;
					viewBeginLine = getBeginLine(viewEndLine);
					adjustVerticalBar();
				}					
			}
		} else
			caretChar++;
		clearSelected();

		redraw();
	}

	// 处理上方向键
	private void handleUpKey() {
		if(caretLine == 0) return;
		else{
			caretLine--;
			if(caretLine < viewBeginLine) {
				viewBeginLine--;
				viewEndLine = getEndLine(viewBeginLine);
				adjustVerticalBar();		
			}
		}
		
		clearSelected();
		GC gc = new GC(this);
		int w = caret.getLocation().x - margin;
		caretChar = ((LineCache)lineBufs.get(caretLine)).getBeginCharIndexLessThanWidth(gc, w);
		gc.dispose();
		redraw();
	}

	// 初始化工作
	private void initVariable() {
		display = getDisplay();
		color = new Color(display, 0xF7, 0xF3, 0xF7);
		// 设置光标
		caret = new Caret(this, SWT.NONE);
		setCaret(caret);
		caret.setLocation(margin, margin);
		GC gc = new GC(this);
		fontMetrics = gc.getFontMetrics();
		caret.setSize(1, fontMetrics.getHeight());
		gc.dispose();
		// 设置鼠标
		beamCursor = new Cursor(display, SWT.CURSOR_IBEAM);
		this.setCursor(beamCursor);
		// 初始化变量
		down = false;
		enabled = true;
		clipboard = new Clipboard(display);
		useEnter = true;
		// 初始化光标位置和缓冲区
		caretLine = caretChar = 0;
		maxChar = 400;
		lineBufs = new ArrayList();
		lineBufs.add(new LineCache());
		// 设置视口坐标和当前行数
		viewBeginLine = viewEndLine = 0;
		lines = 1;
		// 设置背景
		setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		// 获得垂直卷滚条
		vBar = this.getVerticalBar();
		vBar.setMinimum(0);
		vBar.setMaximum(lines);
		vBar.setIncrement(1);
		vBar.setVisible(false);
		vBar.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					handleScroll();
				}
			}
		);
		// 添加监听器
		addPaintListener(this);
		addDisposeListener(this);
		addMouseListener(this);
		addKeyListener(this);
		addTraverseListener(this);
		addMouseMoveListener(this);
		addControlListener(this);
	}
	
	// 处理滚动事件
	private void handleScroll() {
		viewBeginLine = vBar.getSelection();
		viewEndLine = getEndLine(viewBeginLine);
		caret.setVisible(false);
		redraw();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
	 */
	public void keyPressed(KeyEvent e) {
		// 如果鼠标按下了,则暂时不响应任何键盘事件
		if(down) {
			e.doit = false;
			return;
		}
		// 检查光标是否在视口之外,这可能是因为卷滚条的原因,需要把光标搞到视口来
		if(caretLine < viewBeginLine || caretLine > viewEndLine) {
			viewBeginLine = caretLine;
			viewEndLine = getEndLine(viewBeginLine);
			caret.setVisible(true);
			adjustVerticalBar();
			redraw();
		}
		if(e.keyCode == SWT.HOME)
			handleHomeKey(e);
		else if(e.keyCode == SWT.END)
			handleEndKey(e);
		else if(e.keyCode == SWT.ARROW_LEFT)
			handleLeftKey();
		else if(e.keyCode == SWT.ARROW_RIGHT)
			handleRightKey();
		else if(e.keyCode == SWT.ARROW_DOWN)
			handleDownKey();
		else if(e.keyCode == SWT.ARROW_UP)
			handleUpKey();
		else if(e.keyCode == SWT.CR && enabled) {
		    if(useEnter  && (e.stateMask & SWT.CTRL) == 0)
		        handleEnterKey();
		    else if(!useEnter  && (e.stateMask & SWT.CTRL) != 0)
		        handleEnterKey();
		} else if(e.keyCode == SWT.BS && enabled)
			handleBackSpaceKey();
		else if(e.keyCode == SWT.DEL && enabled)
			handleDeleteKey();
		else if(e.character == 0x01) // Ctrl + A
			handleCtrlA();
		else if(e.character == 0x03) // Ctrl + C
			handleCtrlC();
		else if(e.character == 0x18 && enabled) // Ctrl + X
			handleCtrlX();
		else if(e.character == 0x16 && enabled) // Ctrl + V
			handleCtrlV();
		else if(e.character != 0 && enabled) {
			// 检查是否有不允许的键按下,如果是,返回
			if(!noLaithKey(e)) return;
			handleCharacter(e.character, 0);
		}
	}

	// 处理粘贴事件
	private void handleCtrlV() {
		String data = (String)clipboard.getContents(TextTransfer.getInstance());
		if(data != null) paste(data);
	}
	
	// 粘贴,会处理data中的表情和换行符号
	private void paste(String data) {
		if(data == null) return;
		List list = parseText(data);				
		int size = list.size();
		for(int i = 0; i < size; i++) {				
			LineCache lineCache = (LineCache)lineBufs.get(caretLine);				
			handleCharacter(lineCache, (char)0, 0, (LineCache)list.get(i), false, false);
			if(i < size - 1)
				handleEnterKey();
		}
	}

	// 处理剪切事件
	private void handleCtrlX() {
		if(selected) {
			LineCache lineCache = (LineCache)lineBufs.get(caretLine);
			handleCharacter(lineCache, (char)0, 0, null, true, true);
			clipboard.setContents(new Object[] { regularCopy }, new Transfer[] { TextTransfer.getInstance()});
		}
	}

	// 处理拷贝事件
	private void handleCtrlC() {
		if(selected) {
			LineCache copyCache = copySelected();
			regularCopy = copyCache.getString();
			clipboard.setContents(new Object[] { regularCopy }, new Transfer[] { TextTransfer.getInstance()});
		}
	}

	// 处理全选事件
	private void handleCtrlA() {
		for(int i = 0; i < lines; i++) {
			LineCache lineCache = (LineCache)lineBufs.get(i);
			lineCache.affected = true;
			lineCache.affectedBegin = 0;
			lineCache.affectedEnd = lineCache.size();		
		}
		affectedBeginLine = 0;
		affectedEndLine = lines - 1;
		selected = true;
		caretLine = caretChar = 0;

		redraw();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
	 */
	public void keyReleased(KeyEvent e) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDoubleClick(MouseEvent e) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDown(MouseEvent e) {
		if(e.button == 3) { // 右键弹出菜单
			if(enabled) {
				enableMenu.setLocation(toDisplay(e.x, e.y));
				enableMenu.setVisible(true);
			} else {
				disableMenu.setLocation(toDisplay(e.x, e.y));
				disableMenu.setVisible(true);
			}
		} else if(e.button == 1) { // 左键设置光标
			GC gc = new GC(this);
			setCaretLine(calcCaretLine(e.y));
			caretChar = calcCaretChar(gc, e.x, caretLine);
			caret.setVisible(false);
			gc.dispose();
			
			clearSelected();
			redraw();
			setFocus();
			affectedBeginLine = caretLine;
			down = true;
			downX = e.x;
			downY = e.y;
			setCapture(true);
		} else if(e.button == 2) { // 中键执行粘贴任务
			handleCtrlV();
		}
	}
	
	// 清除所有被影响的标志,如果selected为true的话
	private void clearSelected() {
		if(selected) {
			selected = false;
			for(int i = affectedBeginLine; i <= affectedEndLine; i++)
				((LineCache)lineBufs.get(i)).affected = false;		
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseMove(MouseEvent e) {
		if(down) {
			// 得到当前鼠标所在的行和字符
			GC gc = new GC(this);
			int cl = calcCaretLine(e.y);
			int cc = calcCaretChar(gc, e.x, cl);			
			gc.dispose();
			
			if(cl == viewEndLine) {
				vBar.setSelection(vBar.getSelection() + 1);
				handleScroll();
			} else if(cl == viewBeginLine){
				vBar.setSelection(vBar.getSelection() - 1);
				handleScroll();
			}
			
			for(int i = 0; i < lines; i++)
				((LineCache)lineBufs.get(i)).affected = false;
			// 如果字符数没变,直接返回
			if(cl == caretLine && cc == caretChar) return;
			// 设置受影响的行
			if(cl == caretLine && cc != caretChar) {
				LineCache lineCache = (LineCache)lineBufs.get(cl);
				lineCache.affected = true;
				lineCache.affectedBegin = Math.min(cc, caretChar);
				lineCache.affectedEnd = Math.max(cc, caretChar);
				selected = true;
				affectedEndLine = caretLine;
			} else if(cl > caretLine) {
				setAffected(caretLine, caretChar, cl, cc);
				selected = true;
				affectedEndLine = cl;
			} else {
				setAffected(cl, cc, caretLine, caretChar);
				selected = true;
				affectedBeginLine = cl;
				affectedEndLine = caretLine;
			}
			redraw();

⌨️ 快捷键说明

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