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

📄 wrappedsyntaxview.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
字号:
/*
 * 02/24/2004
 *
 * WrappedSyntaxView.java - The View object used by RSyntaxTextArea when
 *                          word wrap is enabled.
 * Copyright (C) 2004 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.fife.ui.rsyntaxtextarea;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.text.*;


/**
 * The <code>javax.swing.text.View</code> object used by
 * <code>RSyntaxTextArea</code> when word wrap is enabled.
 * It implements syntax highlighting for programming languages
 * in a single font with word wrap.  Note that this view is NOT aware of
 * <code>RSyntaxTextArea</code>'s different styles per token type.
 *
 * @author Robert Futrell
 * @version 0.4
 */
public class WrappedSyntaxView extends WrappedPlainView {


	/**
	 * This is reused to keep from allocating/deallocating.
	 */
	private Segment s;
	
	/**
	 * Another variable initialized once to keep from allocating/deallocating.
	 * This is used when determining whether a child view is in the graphics
	 * context's clip bounds.
	 */
	private Rectangle tempRect;

	/**
	 * Used in loops below so we don't have to keep allocating.
	 */
	private Token token;

	/**
	 * Cached for each paint() call so each drawLine() call has access to it.
	 */
	private RSyntaxTextArea host;
	private FontMetrics metrics;
	private SyntaxHighlightingColorScheme colorScheme;

	/**
	 * The end-of-line marker.
	 */
	private static final char[] eolMarker = { '.' };


/*****************************************************************************/


	/**
	 * Constructs a new <code>WrappedSyntaxView</code> wrapped around an element.
	 *
	 * @param elem The element representing the text to display.
	 */
	public WrappedSyntaxView(Element elem) {

		super(elem, true);

		s = new Segment();
		tempRect = new Rectangle();

	}


/*****************************************************************************/


	/**
	 * Draws text at a specified location, taking tabs into account.<br><br>
	 *
	 * NOTE:  This is basically ripped off from
	 * <code>javax.swing.text.Utilities</code>, but slightly optimized for our
	 * situation.
	 *
	 * @param token The token to paint.
	 * @param x The x-coordinate at which to paint.
	 * @param y The y-coordinate at which to paint.
	 * @param g The graphics context in which to paint.
	 * @param startOffset The offset into the current document at which
	 *                    <code>text</code> begins.
	 * @return The x-coordinate representing the end of the painted text.
	 */
	public final int drawTabbedText(Token token, int x, int y,
									Graphics g, int startOffset,
									Color fg, Color bg) {

		char[] text = token.text;
		int start = token.textOffset;
		int end = start + token.textCount;
		int nextX = x;
		int flushLen = 0;
		int flushIndex = start;
		for (int i=start; i<end; i++) {
			if (text[i] == '\t') {
				if (flushLen > 0) {
					g.setColor(fg);
					g.drawChars(text, flushIndex, flushLen, x, y);
					flushLen = 0;
				}
				flushIndex = i + 1;
				int nextNextX = (int)nextTabStop((float)nextX, startOffset+i);
				if (bg!=null) {
					Graphics2D xorGfx = (Graphics2D)g.create();
					Color hostBG = host.getBackground();
					xorGfx.setXORMode(hostBG!=null ? hostBG : Color.WHITE);
					xorGfx.setColor(bg);
					xorGfx.fillRect(nextX,y-metrics.getAscent(), nextNextX-nextX,metrics.getHeight());
					xorGfx.dispose();
				}
				nextX = x = nextNextX;
			}
			else {
				flushLen += 1;
				nextX += metrics.charWidth(text[i]);
			}
		}

		if (flushLen > 0) {
			if (bg!=null) {
				Graphics2D xorGfx = (Graphics2D)g.create();
				Color hostBG = host.getBackground();
				xorGfx.setXORMode(hostBG!=null ? hostBG : Color.WHITE);
				xorGfx.setColor(bg);
				xorGfx.fillRect(x,y-metrics.getAscent(), nextX-x,metrics.getHeight());
				xorGfx.dispose();
			}
			g.setColor(fg);
			g.drawChars(text, flushIndex, flushLen, x, y);
		}

		return nextX;

	}


/*****************************************************************************/


	/**
	 * Draws a single view (i.e., a line of text for a wrapped view), wrapping
	 * the text onto multiple lines if necessary.
	 *
	 * @param g The graphics context in which to paint.
	 * @param r The rectangle in which to paint.
	 * @param view The <code>View</code> to paint.
	 * @param fontHeight The height of the font being used.
	 * @param y The y-coordinate at which to begin painting.
	 */
	protected void drawView(Graphics g, Rectangle r, View view,
						int fontHeight, int y) {

		int x = r.x;

		LayeredHighlighter dh = (LayeredHighlighter)host.getHighlighter();

		RSyntaxDocument document = (RSyntaxDocument)getDocument();
		Element map = getElement();

		int p0 = view.getStartOffset();
		int p1 = view.getEndOffset();

		int lineNumber = map.getElementIndex(p0);

//		try {
//			document.getText(p0,p1-p0-1, s);
//		} catch (BadLocationException ble) {
//			ble.printStackTrace();
//			System.exit(0);
//		}
		int start = p0 - s.offset;
//		token = document.getTokenList(s, p0, lineNumber);
token = document.getTokenListForLine(lineNumber);
		while (token!=null && token.isPaintable()) {
			
			int p = calculateBreakPosition(p0, p1);
			
			if (p==p1)
				dh.paintLayeredHighlights(g, p0,p-1, r, host, this);
			else
				dh.paintLayeredHighlights(g, p0,p, r, host, this);
			
			while (token!=null && token.isPaintable() && token.offset+token.textCount-1<=p) {
				SyntaxScheme scheme = colorScheme.syntaxSchemes[token.type];
				// DON'T call Token.paint, as this view doesn't respect
				// token styles.
				x = drawTabbedText(token, x,y, g, token.offset,
								scheme.foreground, scheme.background);
				token = token.getNextToken();
			}
			
			if (token!=null && token.isPaintable() && token.offset<p) {
					int tokenOffset = token.offset;
					Token temp = new DefaultToken(s, tokenOffset-start,p-1-start, tokenOffset, token.type);
					SyntaxScheme scheme = colorScheme.syntaxSchemes[token.type];
					// DON'T call Token.paint, as this view doesn't respect
					// token styles.
					drawTabbedText(temp, x,y, g, token.offset,
								scheme.foreground, scheme.background);
					temp = token.getNextToken();
					token = new DefaultToken(s, p-start,tokenOffset+token.textCount-1-start, p, token.type);
					token.setNextToken(temp);
					temp = null;
			}

			p0 = (p==p0) ? p1 : p;
			x = r.x;
			y += fontHeight;
			
		} // End of while (token!=null && token.type>Token.NULL).

	}


/*****************************************************************************/


	/**
	 * Paints the word-wrapped text.
	 *
	 * @param g The graphics context in which to paint.
	 * @param a The shape (usually a rectangle) in which to paint.
	 */
	public void paint(Graphics g, Shape a) {

		Rectangle alloc = (a instanceof Rectangle) ?
							(Rectangle)a : a.getBounds();

		host = (RSyntaxTextArea)getContainer();
		colorScheme = host.getSyntaxHighlightingColorScheme();
		metrics = g.getFontMetrics();
		int ascent = metrics.getAscent();
		int fontHeight = metrics.getHeight();

		int n = getViewCount();	// Number of lines.
		int x = alloc.x + getLeftInset();
		int y = alloc.y + getTopInset();
		Rectangle clip = g.getClipBounds();
		for (int i = 0; i < n; i++) {
			tempRect.x = x + getOffset(X_AXIS, i);
			tempRect.y = y + getOffset(Y_AXIS, i);
			tempRect.width = getSpan(X_AXIS, i);
			tempRect.height = getSpan(Y_AXIS, i);
			//System.err.println("For line " + i + ": tempRect==" + tempRect);
			if (tempRect.intersects(clip)) {
				View view = getView(i);
				drawView(g, alloc, view, fontHeight, tempRect.y+ascent);
			}
		}

	}


/*****************************************************************************/

}

⌨️ 快捷键说明

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