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

📄 textareapainter.java

📁 用java 编写的源码开放的文本编辑器。有很多有用的特性
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	{		return extensionMgr.getExtensions();	} //}}}	//{{{ getToolTipText() method	/**	 * Returns the tool tip to display at the specified location.	 * @param evt The mouse event	 */	public String getToolTipText(MouseEvent evt)	{		if(!textArea.getBuffer().isLoaded())			return null;		return extensionMgr.getToolTipText(evt.getX(),evt.getY());	} //}}}	//{{{ getFontMetrics() method	/**	 * Returns the font metrics used by this component.	 */	public FontMetrics getFontMetrics()	{		return fm;	} //}}}	//{{{ setFont() method	/**	 * Sets the font for this component. This is overridden to update the	 * cached font metrics and to recalculate which lines are visible.	 * @param font The font	 */	public void setFont(Font font)	{		super.setFont(font);		fm = getFontMetrics(font);		textArea.recalculateVisibleLines();	} //}}}	//{{{ paintComponent() method	/**	 * Repaints the text.	 * @param g The graphics context	 */	public void paintComponent(Graphics _gfx)	{		Graphics2D gfx = (Graphics2D)_gfx;		gfx.setRenderingHints(renderingHints);		fontRenderContext = gfx.getFontRenderContext();		Rectangle clipRect = gfx.getClipBounds();		gfx.setColor(getBackground());		gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height);		Buffer buffer = textArea.getBuffer();		if(!buffer.isLoaded())			return;		int x = textArea.getHorizontalOffset();		int height = fm.getHeight();		int firstInvalid = clipRect.y / height;		// Because the clipRect's height is usually an even multiple		// of the font height, we subtract 1 from it, otherwise one		// too many lines will always be painted.		int lastInvalid = (clipRect.y + clipRect.height - 1) / height;		//if(lastInvalid - firstInvalid > 1)		//	System.err.println("repainting " + (lastInvalid - firstInvalid) + " lines");		textArea.chunkCache.updateChunksUpTo(lastInvalid);		int y = (clipRect.y - clipRect.y % height);		try		{			boolean updateMaxHorizontalScrollWidth = false;			for(int line = firstInvalid; line <= lastInvalid; line++)			{				ChunkCache.LineInfo lineInfo = textArea.chunkCache					.getLineInfo(line);				if(!lineInfo.chunksValid)					System.err.println("text area painter: not valid");				lineInfo.width = paintLine(gfx,buffer,lineInfo,line,x,y) - x;				if(lineInfo.width > textArea.maxHorizontalScrollWidth)					updateMaxHorizontalScrollWidth = true;				y += height;			}			if(buffer.isNextLineRequested())			{				//System.err.println("next line requested");				int h = clipRect.y + clipRect.height;				textArea.chunkCache.invalidateChunksFrom(lastInvalid + 1);				repaint(0,h,getWidth(),getHeight() - h);			}			if(updateMaxHorizontalScrollWidth)				textArea.updateMaxHorizontalScrollWidth();		}		catch(Exception e)		{			Log.log(Log.ERROR,this,"Error repainting line"				+ " range {" + firstInvalid + ","				+ lastInvalid + "}:");			Log.log(Log.ERROR,this,e);		}		if(textArea.timing)		{			textArea.timing = false;			System.err.println(System.currentTimeMillis() - textArea.time);		}	} //}}}	//{{{ nextTabStop() method	/**	 * Implementation of TabExpander interface. Returns next tab stop after	 * a specified point.	 * @param x The x co-ordinate	 * @param tabOffset Ignored	 * @return The next tab stop after <i>x</i>	 */	public float nextTabStop(float x, int tabOffset)	{		int ntabs = (int)(x / textArea.tabSize);		return (ntabs + 1) * textArea.tabSize;	} //}}}	//{{{ getPreferredSize() method	/**	 * Returns the painter's preferred size.	 */	public Dimension getPreferredSize()	{		Dimension dim = new Dimension();		char[] foo = new char[80];		for(int i = 0; i < foo.length; i++)			foo[i] = ' ';		dim.width = (int)(getFont().getStringBounds(foo,0,foo.length,			fontRenderContext).getWidth());		dim.height = fm.getHeight() * 25;		return dim;	} //}}}	//{{{ getMinimumSize() method	/**	 * Returns the painter's minimum size.	 */	public Dimension getMinimumSize()	{		return getPreferredSize();	} //}}}	//{{{ Private members	//{{{ Instance variables	private JEditTextArea textArea;	private SyntaxStyle[] styles;	private Color caretColor;	private Color selectionColor;	private Color lineHighlightColor;	private Color bracketHighlightColor;	private Color eolMarkerColor;	private Color wrapGuideColor;	private SyntaxStyle foldLineStyle;	private boolean blockCaret;	private boolean lineHighlight;	private boolean bracketHighlight;	private boolean eolMarkers;	private boolean wrapGuide;	private boolean antiAlias;	private boolean fracFontMetrics;	// should try to use this as little as possible.	private FontMetrics fm;	private ExtensionManager extensionMgr;	// we keep a reference to this to obtain the background color and	// collapsed fold state of the last painted line	private PaintLineBackground lineBackground;	private RenderingHints renderingHints;	private FontRenderContext fontRenderContext;	//}}}	//{{{ updateRenderingHints() method	private void updateRenderingHints()	{		HashMap hints = new HashMap();		if(antiAlias)		{			hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);			hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);			hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);		}		else		{			hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);			hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);		}		hints.put(RenderingHints.KEY_FRACTIONALMETRICS,			fracFontMetrics ?				RenderingHints.VALUE_FRACTIONALMETRICS_ON				: RenderingHints.VALUE_FRACTIONALMETRICS_OFF);		renderingHints = new RenderingHints(hints);		fontRenderContext = new FontRenderContext(null,antiAlias,			fracFontMetrics);	} //}}}	//{{{ paintLine() method	private int paintLine(Graphics2D gfx, Buffer buffer,		ChunkCache.LineInfo lineInfo, int screenLine,		int x, int y)	{		int physicalLine = lineInfo.physicalLine;		if(physicalLine == -1)			extensionMgr.paintInvalidLine(gfx,screenLine,y);		else		{			int start = textArea.getScreenLineStartOffset(screenLine);			int end = textArea.getScreenLineEndOffset(screenLine);			extensionMgr.paintValidLine(gfx,screenLine,physicalLine,				start,end,y);			Font defaultFont = getFont();			Color defaultColor = getForeground();			gfx.setFont(defaultFont);			gfx.setColor(defaultColor);			float baseLine = y + fm.getHeight()				- fm.getLeading() - fm.getDescent();			if(lineInfo.chunks != null)			{				buffer.getLineText(physicalLine,textArea.lineSegment);				x += Chunk.paintChunkList(textArea.lineSegment,					lineInfo.chunks,gfx,x,baseLine,					lineBackground.bgColor,true);			}			if(!lineInfo.lastSubregion)			{				gfx.setFont(defaultFont);				gfx.setColor(eolMarkerColor);				gfx.drawString(":",Math.max(x,					textArea.getHorizontalOffset()					+ textArea.wrapMargin + textArea.charWidth),					baseLine);				x += textArea.charWidth;			}			else if(lineBackground.collapsedFold)			{				Font font = foldLineStyle.getFont();				gfx.setFont(font);				gfx.setColor(foldLineStyle.getForegroundColor());				int nextLine = textArea.getFoldVisibilityManager()					.getNextVisibleLine(physicalLine);				if(nextLine == -1)					nextLine = buffer.getLineCount();				int count = nextLine - physicalLine - 1;				String str = " [" + count + " lines]";				float width = (float)font.getStringBounds(					str,fontRenderContext).getWidth();				gfx.drawString(str,x,baseLine);				x += width;			}			else if(eolMarkers)			{				gfx.setFont(defaultFont);				gfx.setColor(eolMarkerColor);				gfx.drawString(".",x,baseLine);				x += textArea.charWidth;			}			paintCaret(gfx,physicalLine,start,end,y,lineBackground.bgColor);		}		return x;	} //}}}	//{{{ paintCaret() method	private void paintCaret(Graphics2D gfx, int physicalLine,		int start, int end, int y, Color bgColor)	{		if(!textArea.isCaretVisible())			return;		int caret = textArea.getCaretPosition();		if(caret < start || caret >= end)			return;		int offset = caret - textArea.getLineStartOffset(physicalLine);		textArea.offsetToXY(physicalLine,offset,textArea.returnValue);		int caretX = textArea.returnValue.x;		int height = fm.getHeight();		gfx.setColor(caretColor);		if(blockCaret)		{			// Workaround for bug in Graphics2D in JDK1.4 under			// Windows; calling setPaintMode() does not reset			// graphics mode.			Graphics2D blockgfx = (Graphics2D)gfx.create();			blockgfx.setXORMode(bgColor);			if(textArea.isOverwriteEnabled())			{				blockgfx.fillRect(caretX,y + height - height / 3,					textArea.charWidth,height / 3);			}			else				blockgfx.fillRect(caretX,y,textArea.charWidth,height);			blockgfx.dispose();		}		else		{			if(textArea.isOverwriteEnabled())			{				gfx.drawLine(caretX,y + height - 1,					caretX + textArea.charWidth,y + height - 1);			}			else				gfx.drawLine(caretX,y,caretX,y + height - 1);		}	} //}}}	//}}}	//{{{ PaintLineBackground class	class PaintLineBackground extends TextAreaExtension	{		boolean collapsedFold;		Color bgColor;		//{{{ paintValidLine() method		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			// minimise access$ methods			JEditTextArea textArea = TextAreaPainter.this.textArea;			Buffer buffer = textArea.getBuffer();			collapsedFold = (physicalLine < buffer.getLineCount() - 1				&& buffer.isFoldStart(physicalLine)				&& !textArea.getFoldVisibilityManager()				.isLineVisible(physicalLine + 1));			int caret = textArea.getCaretPosition();			boolean paintLineHighlight = isLineHighlightEnabled()				&& caret >= start && caret < end				&& textArea.selection.size() == 0;			if(paintLineHighlight)				bgColor = lineHighlightColor;			else if(collapsedFold)			{				bgColor = foldLineStyle.getBackgroundColor();				if(bgColor == null)					bgColor = getBackground();			}			else				bgColor = getBackground();			if(paintLineHighlight || collapsedFold)			{				gfx.setColor(bgColor);				gfx.fillRect(0,y,getWidth(),fm.getHeight());			}		} //}}}	} //}}}	//{{{ PaintSelection class	class PaintSelection extends TextAreaExtension	{		//{{{ paintValidLine() method		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			if(textArea.selection.size() == 0)				return;			gfx.setColor(getSelectionColor());			for(int i = textArea.selection.size() - 1;				i >= 0; i--)			{				paintSelection(gfx,screenLine,					physicalLine,start,end,y,					(Selection)textArea.selection					.get(i));			}		} //}}}		//{{{ paintSelection() method		private void paintSelection(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y, Selection s)		{			if(end <= s.start || start > s.end)				return;			int selStartScreenLine = textArea.getScreenLineOfOffset(s.start);			int selEndScreenLine = textArea.getScreenLineOfOffset(s.end);			Buffer buffer = textArea.getBuffer();			int lineStart = buffer.getLineStartOffset(physicalLine);			int x1, x2;			if(s instanceof Selection.Rect)			{				start -= lineStart;				end -= lineStart;				Selection.Rect rect = (Selection.Rect)s;				int _start = rect.getStartColumn(buffer);				int _end = rect.getEndColumn(buffer);				int lineLen = buffer.getLineLength(physicalLine);				int[] total = new int[1];				int rectStart = buffer.getOffsetOfVirtualColumn(					physicalLine,_start,total);				if(rectStart == -1)				{					x1 = (_start - total[0]) * textArea.charWidth;					rectStart = lineLen;				}				else					x1 = 0;				int rectEnd = buffer.getOffsetOfVirtualColumn(					physicalLine,_end,total);				if(rectEnd == -1)				{					x2 = (_end - total[0]) * textArea.charWidth;					rectEnd = lineLen;				}				else					x2 = 0;				if(end <= rectStart || start > rectEnd)					return;				x1 = (rectStart < start ? 0					: x1 + textArea.offsetToXY(physicalLine,rectStart,textArea.returnValue).x);				x2 = (rectEnd > end ? getWidth()					: x2 + textArea.offsetToXY(physicalLine,rectEnd,textArea.returnValue).x);			}			else if(selStartScreenLine == selEndScreenLine				&& selStartScreenLine != -1)			{				x1 = textArea.offsetToXY(physicalLine,					s.start - lineStart,textArea.returnValue).x;				x2 = textArea.offsetToXY(physicalLine,					s.end - lineStart,textArea.returnValue).x;			}			else if(screenLine == selStartScreenLine)			{				x1 = textArea.offsetToXY(physicalLine,					s.start - lineStart,textArea.returnValue).x;				x2 = getWidth();			}			else if(screenLine == selEndScreenLine)			{				x1 = 0;				x2 = textArea.offsetToXY(physicalLine,					s.end - lineStart,textArea.returnValue).x;			}			else			{				x1 = 0;				x2 = getWidth();			}			if(x1 < 0)				x1 = 0;			if(x2 < 0)				x2 = 0;			if(x1 == x2)				x2++;			gfx.fillRect(x1,y,x2 - x1,fm.getHeight());		} //}}}	} //}}}	//{{{ WrapGuide class	class WrapGuide extends TextAreaExtension	{		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			paintInvalidLine(gfx,screenLine,y);		}		public void paintInvalidLine(Graphics2D gfx, int screenLine, int y)		{			if(!textArea.wrapToWidth && textArea.wrapMargin != 0				&& isWrapGuidePainted())			{				gfx.setColor(getWrapGuideColor());				int x = textArea.getHorizontalOffset() + textArea.wrapMargin;				gfx.drawLine(x,y,x,y + fm.getHeight());			}		}		public String getToolTipText(int x, int y)		{			if(!textArea.wrapToWidth && textArea.wrapMargin != 0				&& isWrapGuidePainted())			{				int wrapGuidePos = textArea.wrapMargin					+ textArea.getHorizontalOffset();				if(Math.abs(x - wrapGuidePos) < 5)				{					return String.valueOf(textArea.getBuffer()						.getProperty("maxLineLen"));				}			}			return null;		}	} //}}}	//{{{ BracketHighlight class	class BracketHighlight extends TextAreaExtension	{		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			if(!isBracketHighlightEnabled() || !textArea.isBracketHighlightVisible())				return;			int bracketLine = textArea.getBracketLine();			int bracketOffset = textArea.getBracketPosition();			if(bracketLine == -1 || bracketOffset == -1)				return;			int bracketLineStart = textArea.getLineStartOffset(bracketLine);			if(bracketOffset + bracketLineStart < start				|| bracketOffset + bracketLineStart >= end)				return;			textArea.offsetToXY(bracketLine,bracketOffset,textArea.returnValue);			gfx.setColor(getBracketHighlightColor());			// Hack!!! Since there is no fast way to get the character			// from the bracket matching routine, we use ( since all			// brackets probably have the same width anyway			gfx.drawRect(textArea.returnValue.x,y,(int)gfx.getFont().getStringBounds(				"(",getFontRenderContext()).getWidth() - 1,				fm.getHeight() - 1);		}	} //}}}}

⌨️ 快捷键说明

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