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

📄 defaultcontent.java

📁 源码为Eclipse开源开发平台桌面开发工具SWT的源代码,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html *  * Contributors: *     IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.swt.custom;import org.eclipse.swt.*;import org.eclipse.swt.internal.Compatibility;import org.eclipse.swt.widgets.*;import java.util.Vector;class DefaultContent implements StyledTextContent {	private final static String LineDelimiter = System.getProperty("line.separator");	Vector textListeners = new Vector(); // stores text listeners for event sending	char[] textStore = new char[0];	// stores the actual text	int gapStart = -1;	// the character position start of the gap	int gapEnd = -1;	// the character position after the end of the gap	int gapLine = -1;	// the line on which the gap exists, the gap will always be associated				// with one line	int highWatermark = 300;		int lowWatermark = 50;				int[][] lines = new int[50][2];	// array of character positions and lengths representing							// the lines of text	int lineCount = 0;	// the number of lines of text		int expandExp = 1; 	// the expansion exponent, used to increase the lines array exponentially	int replaceExpandExp = 1; 	// the expansion exponent, used to increase the lines array exponentially/**  * Creates a new DefaultContent and initializes it.  A <code>StyledTextContent</> will always have * at least one empty line. */DefaultContent() {	super();	setText("");}/**  * Adds a line to the end of the line indexes array.  Increases the size of the array if necessary. * <code>lineCount</code> is updated to reflect the new entry. * <p> * * @param start the start of the line * @param length the length of the line */void addLineIndex(int start, int length) {	int size = lines.length;	if (lineCount == size) {		// expand the lines by powers of 2		int[][] newLines = new int[size+Compatibility.pow2(expandExp)][2];		System.arraycopy(lines, 0, newLines, 0, size);		lines = newLines;		expandExp++;	}	int[] range = new int[] {start, length};	lines[lineCount] = range;	lineCount++;}/**  * Adds a line index to the end of <code>linesArray</code>.  Increases the  * size of the array if necessary and returns a new array. * <p> * * @param start the start of the line * @param length the length of the line * @param linesArray the array to which to add the line index * @param count the position at which to add the line * @return a new array of line indexes */int[][] addLineIndex(int start, int length, int[][] linesArray, int count) {	int size = linesArray.length;	int[][] newLines = linesArray;	if (count == size) {		newLines = new int[size+Compatibility.pow2(replaceExpandExp)][2];		replaceExpandExp++;		System.arraycopy(linesArray, 0, newLines, 0, size);	}	int[] range = new int[] {start, length};	newLines[count] = range;	return newLines;}/** * Adds a <code>TextChangeListener</code> listening for  * <code>TextChangingEvent</code> and <code>TextChangedEvent</code>. A  * <code>TextChangingEvent</code> is sent before changes to the text occur. * A <code>TextChangedEvent</code> is sent after changes to the text  * occured. * <p> * * @param listener the listener * @exception IllegalArgumentException <ul> *    <li>ERROR_NULL_ARGUMENT when listener is null</li> * </ul> */public void addTextChangeListener(TextChangeListener listener) {	if (listener == null) error(SWT.ERROR_NULL_ARGUMENT);	StyledTextListener typedListener = new StyledTextListener(listener);	textListeners.addElement(typedListener);	}	/** * Adjusts the gap to accomodate a text change that is occurring. * <p> * * @param position the position at which a change is occurring * @param sizeHint the size of the change * @param line the line where the gap will go */void adjustGap(int position, int sizeHint, int line) {	if (position == gapStart) {		// text is being inserted at the gap position		int size = (gapEnd - gapStart) - sizeHint;		if (lowWatermark <= size && size <= highWatermark)			return;	} else if ((position + sizeHint == gapStart) && (sizeHint < 0)) {		// text is being deleted at the gap position		int size = (gapEnd - gapStart) - sizeHint;		if (lowWatermark <= size && size <= highWatermark)			return;	}	moveAndResizeGap(position, sizeHint, line);}/** * Calculates the indexes of each line in the text store.  Assumes no gap exists.   * Optimized to do less checking. */void indexLines(){	int start = 0;	lineCount = 0;	int textLength = textStore.length;	int i;	for (i=start; i<textLength; i++) { 		char ch = textStore[i];							if (ch == SWT.CR) {			// see if the next character is a LF			if (i + 1 < textLength) {				ch = textStore[i+1];				if (ch == SWT.LF) {					i++;				}			}			addLineIndex(start, i - start + 1);			start = i + 1;		} else if (ch == SWT.LF) {			addLineIndex(start, i - start + 1);			start = i + 1;		} 	}				addLineIndex(start, i - start);}/**  * Returns whether or not the given character is a line delimiter.  Both CR and LF  * are valid line delimiters. * <p> * * @param ch the character to test * @return true if ch is a delimiter, false otherwise */boolean isDelimiter(char ch) {	if (ch == SWT.CR) return true;	if (ch == SWT.LF) return true;	return false;}	/** * Determine whether or not the replace operation is valid.  DefaultContent will not allow * the /r/n line delimiter to be split or partially deleted. * <p> * * @param start	start offset of text to replace * @param replaceLength start offset of text to replace * @param newText start offset of text to replace */protected boolean isValidReplace(int start, int replaceLength, String newText){	if (replaceLength == 0) {		// inserting text, see if the \r\n line delimiter is being split		if (start == 0) return true;		if (start == getCharCount()) return true;		char before = getTextRange(start - 1, 1).charAt(0);		if (before == '\r') {			char after = getTextRange(start, 1).charAt(0);			if (after == '\n') return false;		}	} else {		// deleting text, see if part of a \r\n line delimiter is being deleted		char startChar = getTextRange(start, 1).charAt(0);		if (startChar == '\n') {			// see if char before delete position is \r			if (start != 0) {				char before = getTextRange(start - 1, 1).charAt(0);				if (before == '\r') return false;			}		}		char endChar = getTextRange(start + replaceLength - 1, 1).charAt(0);		if (endChar == '\r') {			// see if char after delete position is \n			if (start + replaceLength != getCharCount()) {				char after = getTextRange(start + replaceLength, 1).charAt(0);				if (after == '\n') return false;			}		}	} 	return true;}/** * Calculates the indexes of each line of text in the given range. * <p> * * @param offset the logical start offset of the text lineate * @param length the length of the text to lineate, includes gap * @param numLines the number of lines to initially allocate for the line index array, *	passed in for efficiency (the exact number of lines may be known) * @return a line indexes array where each line is identified by a start offset and  * 	a length */int[][] indexLines(int offset, int length, int numLines){	int[][] indexedLines = new int[numLines][2];	int start = 0;	int lineCnt = 0;	int i;	replaceExpandExp = 1;	for (i=start; i<length; i++) {		int location = i + offset; 		if ((location >= gapStart) && (location < gapEnd)) {			// ignore the gap		} else {			char ch = textStore[location];							if (ch == SWT.CR) {				// see if the next character is a LF				if (location+1 < textStore.length) {					ch = textStore[location+1];					if (ch == SWT.LF) {						i++;					} 				}				indexedLines = addLineIndex(start, i - start + 1, indexedLines, lineCnt);				lineCnt++;				start = i + 1;			} else if (ch == SWT.LF) {				indexedLines = addLineIndex(start, i - start + 1, indexedLines, lineCnt);				lineCnt++;				start = i + 1;			} 		}	}	int[][] newLines = new int[lineCnt+1][2];	System.arraycopy(indexedLines, 0, newLines, 0, lineCnt);	int[] range = new int[] {start, i - start};	newLines[lineCnt]=range;	return newLines; }/** * Inserts text. * <p> * * @param position the position at which to insert the text * @param length the text to insert */void insert(int position, String text) {		if (text.length() == 0) return;					int startLine = getLineAtOffset(position);	int change = text.length();	boolean endInsert = position == getCharCount();	adjustGap(position, change, startLine);	// during an insert the gap will be adjusted to start at	// position and it will be associated with startline, the	// inserted text will be placed in the gap			int startLineOffset = getOffsetAtLine(startLine);	// at this point, startLineLength will include the start line	// and all of the newly inserted text	int	startLineLength = getPhysicalLine(startLine).length();		if (change > 0) {		// shrink gap 		gapStart += (change);		for (int i = 0; i < text.length(); i++)			textStore[position + i]= text.charAt(i);	}			// figure out the number of new lines that have been inserted	int [][] newLines = indexLines(startLineOffset, startLineLength, 10);	// only insert an empty line if it is the last line in the text	int numNewLines = newLines.length - 1;	if (newLines[numNewLines][1] == 0) {		// last inserted line is a new line		if (endInsert) {			// insert happening at end of the text, leave numNewLines as			// is since the last new line will not be concatenated with another			// line 			numNewLines += 1;		} else {			numNewLines -= 1;		}	}		// make room for the new lines	expandLinesBy(numNewLines);	// shift down the lines after the replace line	for (int i = lineCount-1; i > startLine; i--) {		lines[i + numNewLines]=lines[i];	}	// insert the new lines	for (int i=0; i<numNewLines; i++) {		newLines[i][0] += startLineOffset;		lines[startLine + i]=newLines[i];	}	// update the last inserted line	if (numNewLines < newLines.length) {		newLines[numNewLines][0] += startLineOffset;		lines[startLine + numNewLines] = newLines[numNewLines];	}		lineCount += numNewLines;	gapLine = getLineAtPhysicalOffset(gapStart);		}/** * Moves the gap and adjusts its size in anticipation of a text change.   * The gap is resized to actual size + the specified size and moved to the given  * position. * <p> * * @param position the position at which a change is occurring * @param sizeHint the size of the change * @param line the line where the gap should be put */void moveAndResizeGap(int position, int size, int newGapLine) {	char[] content = null;	int oldSize = gapEnd - gapStart;	int newSize;	if (size > 0) {		newSize = highWatermark + size;	} else {		newSize = lowWatermark - size;	}	// remove the old gap from the lines information	if (gapExists()) {		// adjust the line length		lines[gapLine][1] = lines[gapLine][1] - oldSize;		// adjust the offsets of the lines after the gapLine		for (int i=gapLine+1; i<lineCount; i++) {			lines[i][0]=lines[i][0]-oldSize;		}	}		if (newSize < 0) {		if (oldSize > 0) {			// removing the gap			content = new char[textStore.length - oldSize];			System.arraycopy(textStore, 0, content, 0, gapStart);			System.arraycopy(textStore, gapEnd, content, gapStart, content.length - gapStart);			textStore= content;		}		gapStart = gapEnd= position;		return;	}	content = new char[textStore.length + (newSize - oldSize)];	int newGapStart = position;	int newGapEnd = newGapStart + newSize;	if (oldSize == 0) {				System.arraycopy(textStore, 0, content, 0, newGapStart);		System.arraycopy(textStore, newGapStart, content, newGapEnd, content.length - newGapEnd);		} else if (newGapStart < gapStart) {		int delta = gapStart - newGapStart;		System.arraycopy(textStore, 0, content, 0, newGapStart);		System.arraycopy(textStore, newGapStart, content, newGapEnd, delta);		System.arraycopy(textStore, gapEnd, content, newGapEnd + delta, textStore.length - gapEnd);	} else {				int delta = newGapStart - gapStart;		System.arraycopy(textStore, 0, content, 0, gapStart);		System.arraycopy(textStore, gapEnd, content, gapStart, delta);		System.arraycopy(textStore, gapEnd + delta, content, newGapEnd, content.length - newGapEnd);	}	textStore = content;	gapStart = newGapStart;	gapEnd = newGapEnd;		// add the new gap to the lines information	if (gapExists()) {		gapLine = newGapLine;		// adjust the line length		int gapLength = gapEnd - gapStart;		lines[gapLine][1] = lines[gapLine][1] + (gapLength);		// adjust the offsets of the lines after the gapLine		for (int i=gapLine+1; i<lineCount; i++) {			lines[i][0]=lines[i][0]+gapLength;		}	}}/**  * Returns the number of lines that are in the specified text. * <p> * * @param startOffset the start of the text to lineate * @param length the length of the text to lineate * @return number of lines */int lineCount(int startOffset, int length){	if (length == 0) {		return 0;	}	int lineCnt = 0;	int count = 0;	int i = startOffset;	if (i >= gapStart) {		i += gapEnd - gapStart;	}	while (count < length) {		if ((i >= gapStart) && (i < gapEnd)) {			// ignore the gap		} else {			char ch = textStore[i];						if (ch == SWT.CR) {				// see if the next character is a LF				if (i + 1 < textStore.length) {					ch = textStore[i+1];					if (ch == SWT.LF) {						i++;						count++;					} 				} 				lineCnt++;			} else if (ch == SWT.LF) {				lineCnt++;			}			count++;		}		i++;	}				return lineCnt;}/**  * Returns the number of lines that are in the specified text. * <p> * * @param text the text to lineate * @return number of lines in the text

⌨️ 快捷键说明

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