📄 styledtext.java
字号:
// systems that don't support Unicode RTF. String cpg = System.getProperty("file.encoding").toLowerCase(); if (cpg.startsWith("cp") || cpg.startsWith("ms")) { cpg = cpg.substring(2, cpg.length()); header.append("\\ansicpg"); header.append(cpg); } header.append("\\uc0\\deff0{\\fonttbl{\\f0\\fnil "); header.append(fontData.getName()); header.append(";}}\n{\\colortbl"); for (int i = 0; i < colorTable.size(); i++) { Color color = (Color) colorTable.elementAt(i); header.append("\\red"); header.append(color.getRed()); header.append("\\green"); header.append(color.getGreen()); header.append("\\blue"); header.append(color.getBlue()); header.append(";"); } // some RTF readers ignore the deff0 font tag. Explicitly // set the font for the whole document to work around this. header.append("}\n{\\f0\\fs"); // font size is specified in half points header.append(fontData.getHeight() * 2); header.append(" "); write(header.toString(), 0); } /** * Appends the specified line text to the RTF data. Lines will be formatted * using the styles queried from the LineStyleListener, if set, or those set * directly in the widget. * <p> * * @param line line text to write as RTF. Must not contain line breaks * Line breaks should be written using writeLineDelimiter() * @param lineOffset offset of the line. 0 based from the start of the * widget document. Any text occurring before the start offset or after the * end offset specified during object creation is ignored. * @exception SWTException <ul> * <li>ERROR_IO when the writer is closed.</li> * </ul> */ public void writeLine(String line, int lineOffset) { StyleRange[] styles = new StyleRange[0]; Color lineBackground = null; StyledTextEvent event; if (isClosed()) { SWT.error(SWT.ERROR_IO); } event = renderer.getLineStyleData(lineOffset, line); if (event != null) { styles = event.styles; } event = renderer.getLineBackgroundData(lineOffset, line); if (event != null) { lineBackground = event.lineBackground; } if (lineBackground == null) { lineBackground = getBackground(); } writeStyledLine(line, lineOffset, styles, lineBackground); } /** * Appends the specified line delmimiter to the RTF data. * <p> * * @param lineDelimiter line delimiter to write as RTF. * @exception SWTException <ul> * <li>ERROR_IO when the writer is closed.</li> * </ul> */ public void writeLineDelimiter(String lineDelimiter) { if (isClosed()) { SWT.error(SWT.ERROR_IO); } write(lineDelimiter, 0, lineDelimiter.length()); write("\\par "); } /** * Appends the specified line text to the RTF data. * Use the colors and font styles specified in "styles" and "lineBackground". * Formatting is written to reflect the text rendering by the text widget. * Style background colors take precedence over the line background color. * Background colors are written using the \highlight tag (vs. the \cb tag). * <p> * * @param line line text to write as RTF. Must not contain line breaks * Line breaks should be written using writeLineDelimiter() * @param lineOffset offset of the line. 0 based from the start of the * widget document. Any text occurring before the start offset or after the * end offset specified during object creation is ignored. * @param styles styles to use for formatting. Must not be null. * @param linebackground line background color to use for formatting. * May be null. */ void writeStyledLine(String line, int lineOffset, StyleRange[] styles, Color lineBackground) { int lineLength = line.length(); int lineIndex; int copyEnd; int startOffset = getStart(); int endOffset = startOffset + super.getCharCount(); int lineEndOffset = Math.min(lineLength, endOffset - lineOffset); int writeOffset = startOffset - lineOffset; if (writeOffset >= line.length()) { return; // whole line is outside write range } else if (writeOffset > 0) { lineIndex = writeOffset; // line starts before RTF write start } else { lineIndex = 0; } if (lineBackground != null) { write("{\\highlight"); write(getColorIndex(lineBackground, DEFAULT_BACKGROUND)); write(" "); } for (int i = 0; i < styles.length; i++) { StyleRange style = styles[i]; int start = style.start - lineOffset; int end = start + style.length; int colorIndex; // skip over partial first line if (end < writeOffset) { continue; } // style starts beyond line end or RTF write end if (start >= lineEndOffset) { break; } // write any unstyled text if (lineIndex < start) { // copy to start of style // style starting betond end of write range or end of line // is guarded against above. write(line, lineIndex, start); lineIndex = start; } // write styled text colorIndex = getColorIndex(style.background, DEFAULT_BACKGROUND); write("{\\cf"); write(getColorIndex(style.foreground, DEFAULT_FOREGROUND)); if (colorIndex != DEFAULT_BACKGROUND) { write("\\highlight"); write(colorIndex); } if (style.fontStyle == SWT.BOLD) { write("\\b"); } write(" "); // copy to end of style or end of write range or end of line copyEnd = Math.min(end, lineEndOffset); // guard against invalid styles and let style processing continue copyEnd = Math.max(copyEnd, lineIndex); write(line, lineIndex, copyEnd); if (style.fontStyle == SWT.BOLD) { write("\\b0"); } write("}"); lineIndex = copyEnd; } // write unstyled text at the end of the line if (lineIndex < lineEndOffset) { write(line, lineIndex, lineEndOffset); } if (lineBackground != null) { write("}"); } } } /** * The <code>TextWriter</code> class is used to write widget content to * a string. Whole and partial lines and line breaks can be written. To write * partial lines, specify the start and length of the desired segment * during object creation. * <p> * </b>NOTE:</b> <code>toString()</code> is guaranteed to return a valid string only after close() * has been called. */ class TextWriter { private StringBuffer buffer; private int startOffset; // offset of first character that will be written private int endOffset; // offset of last character that will be written. // 0 based from the beginning of the widget text. private boolean isClosed = false; /** * Creates a writer that writes content starting at offset "start" * in the document. <code>start</code> and <code>length</code> can be set to specify partial lines. * <p> * * @param start start offset of content to write, 0 based from beginning of document * @param length length of content to write */ public TextWriter(int start, int length) { buffer = new StringBuffer(length); startOffset = start; endOffset = start + length; } /** * Closes the writer. Once closed no more content can be written. * <b>NOTE:</b> <code>toString()</code> is not guaranteed to return a valid string unless * the writer is closed. */ public void close() { if (isClosed == false) { isClosed = true; } } /** * Returns the number of characters to write. */ public int getCharCount() { return endOffset - startOffset; } /** * Returns the offset where writing starts. 0 based from the start of * the widget text. Used to write partial lines. */ public int getStart() { return startOffset; } /** * Returns whether the writer is closed. */ public boolean isClosed() { return isClosed; } /** * Returns the string. <code>close()</code> must be called before <code>toString()</code> * is guaranteed to return a valid string. * <p> * * @return the string */ public String toString() { return buffer.toString(); } /** * Appends the given string to the data. */ void write(String string) { buffer.append(string); } /** * Inserts the given string to the data at the specified offset. * Do nothing if "offset" is < 0 or > getCharCount() * <p> * * @param string text to insert * @param offset offset in the existing data to insert "string" at. */ void write(String string, int offset) { if (offset < 0 || offset > buffer.length()) { return; } buffer.insert(offset, string); } /** * Appends the given int to the data. */ void write(int i) { buffer.append(i); } /** * Appends the given character to the data. */ void write(char i) { buffer.append(i); } /** * Appends the specified line text to the data. * <p> * * @param line line text to write. Must not contain line breaks * Line breaks should be written using writeLineDelimiter() * @param lineOffset offset of the line. 0 based from the start of the * widget document. Any text occurring before the start offset or after the * end offset specified during object creation is ignored. * @exception SWTException <ul> * <li>ERROR_IO when the writer is closed.</li> * </ul> */ public void writeLine(String line, int lineOffset) { int lineLength = line.length(); int lineIndex; int copyEnd; int writeOffset = startOffset - lineOffset; if (isClosed) { SWT.error(SWT.ERROR_IO); } if (writeOffset >= lineLength) { return; // whole line is outside write range } else if (writeOffset > 0) { lineIndex = writeOffset; // line starts before write start } else { lineIndex = 0; } copyEnd = Math.min(lineLength, endOffset - lineOffset); if (lineIndex < copyEnd) { write(line.substring(lineIndex, copyEnd)); } } /** * Appends the specified line delmimiter to the data. * <p> * * @param lineDelimiter line delimiter to write * @exception SWTException <ul> * <li>ERROR_IO when the writer is closed.</li> * </ul> */ public void writeLineDelimiter(String lineDelimiter) { if (isClosed) { SWT.error(SWT.ERROR_IO); } write(lineDelimiter); } } /** * LineCache provides an interface to calculate and invalidate * line based data. * Implementors need to return a line width in <code>getWidth</code>. */ interface LineCache { /** * Calculates the lines in the specified range. * <p> * * @param startLine first line to calculate * @param lineCount number of lines to calculate */ public void calculate(int startLine, int lineCount); /** * Returns a width that will be used by the <code>StyledText</code> * widget to size a horizontal scroll bar. * <p> * * @return the line width */ public int getWidth(); /** * Resets the lines in the specified range. * This method is called in <code>StyledText.redraw()</code> * and allows implementors to call redraw themselves during reset. * <p> * * @param startLine the first line to reset * @param lineCount the number of lines to reset * @param calculateMaxWidth true=implementors should retain a * valid width even if it is affected by the reset operation. * false=the width may be set to 0 */ public void redrawReset(int startLine, int lineCount, boolean calculateMaxWidth); /** * Resets the lines in the specified range. * <p> * * @param startLine the first line to reset * @param lineCount the number of lines to reset * @param calculateMaxWidth true=implementors should retain a * valid width even if it is affected by the reset operation. * false=the width may be set to 0 */ public void reset(int startLine, int lineCount, boolean calculateMaxWidth); /** * Called when a text change occurred. * <p> * * @param startOffset the start offset of the text change * @param newLineCount the number of inserted lines * @param replaceLineCount the number of deleted lines * @param newCharCount the number of new characters * @param replaceCharCount the number of deleted characters */ public void textChanged(int startOffset, int newLineCount, int replaceLineCount, int newCharCount, int replaceCharCount); } /** * Keeps track of line widths and the longest line in the * StyledText document. * Line widths are calculated when requested by a call to * <code>calculate</code> and cached until reset by a call * to <code>redrawReset</code> or <code>reset</code>.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -