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

📄 textareapainter.java

📁 开源的java 编辑器源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 */	public void addExtension(TextAreaExtension extension)	{		extensionMgr.addExtension(DEFAULT_LAYER,extension);		repaint();	} //}}}	//{{{ addExtension() method	/**	 * Adds a text area extension, which can perform custom painting and	 * tool tip handling.	 * @param layer The layer to add the extension to. Note that more than	 * extension can share the same layer.	 * @param extension The extension	 * @since jEdit 4.0pre4	 */	public void addExtension(int layer, TextAreaExtension extension)	{		extensionMgr.addExtension(layer,extension);		repaint();	} //}}}	//{{{ removeExtension() method	/**	 * Removes a text area extension. It will no longer be asked to	 * perform custom painting and tool tip handling.	 * @param extension The extension	 * @since jEdit 4.0pre4	 */	public void removeExtension(TextAreaExtension extension)	{		extensionMgr.removeExtension(extension);		repaint();	} //}}}	//{{{ getExtensions() method	/**	 * Returns an array of registered text area extensions. Useful for	 * debugging purposes.	 * @since jEdit 4.1pre5	 */	public TextAreaExtension[] getExtensions()	{		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();		textArea.propertiesChanged();	} //}}}	//{{{ 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(Debug.PAINT_TIMER && lastInvalid - firstInvalid >= 1)			Log.log(Log.DEBUG,this,"repainting " + (lastInvalid - firstInvalid) + " lines");		int y = (clipRect.y - clipRect.y % height);		extensionMgr.paintScreenLineRange(textArea,gfx,			firstInvalid,lastInvalid,y,height);		textArea.updateMaxHorizontalScrollWidth();		textArea.displayManager._notifyScreenLineChanges();	} //}}}	//{{{ 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();	} //}}}	//{{{ Package-private members	//{{{ Instance variables	/* package-private since they are accessed by inner classes and we	 * want this to be fast */	JEditTextArea textArea;	SyntaxStyle[] styles;	Color caretColor;	Color selectionColor;	Color multipleSelectionColor;	Color lineHighlightColor;	Color structureHighlightColor;	Color eolMarkerColor;	Color wrapGuideColor;	SyntaxStyle[] foldLineStyle;	boolean blockCaret;	boolean lineHighlight;	boolean structureHighlight;	boolean eolMarkers;	boolean wrapGuide;	boolean antiAlias;	boolean fracFontMetrics;	// should try to use this as little as possible.	FontMetrics fm;	//}}}	//{{{ TextAreaPainter constructor	/**	 * Creates a new painter. Do not create instances of this class	 * directly.	 */	TextAreaPainter(JEditTextArea textArea)	{		enableEvents(AWTEvent.FOCUS_EVENT_MASK			| AWTEvent.KEY_EVENT_MASK			| AWTEvent.MOUSE_EVENT_MASK);		this.textArea = textArea;		fonts = new HashMap();		extensionMgr = new ExtensionManager();		setAutoscrolls(true);		setOpaque(true);		setRequestFocusEnabled(false);		setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));		fontRenderContext = new FontRenderContext(null,false,false);		addExtension(LINE_BACKGROUND_LAYER,new PaintLineBackground());		addExtension(SELECTION_LAYER,new PaintSelection());		addExtension(WRAP_GUIDE_LAYER,new PaintWrapGuide());		addExtension(BRACKET_HIGHLIGHT_LAYER,new StructureMatcher			.Highlight(textArea));		addExtension(TEXT_LAYER,new PaintText());		caretExtension = new PaintCaret();	} //}}}	//}}}	//{{{ Private members	//{{{ Instance variables	private ExtensionManager extensionMgr;	private PaintCaret caretExtension;	private RenderingHints renderingHints;	private FontRenderContext fontRenderContext;	private HashMap fonts;	//}}}	//{{{ 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);	} //}}}	//{{{ getCharWidth() method	private int getCharWidth(Font font)	{		Integer returnValue = (Integer)fonts.get(font);		if(returnValue == null)		{			int minWidth = Integer.MAX_VALUE;			int maxWidth = Integer.MIN_VALUE;			FontMetrics fm = getFontMetrics(font);			int[] widths = fm.getWidths();			for(int i = 0; i < widths.length; i++)			{				int width = widths[i];				if(width == 0 || !font.canDisplay((char)i))					continue;				minWidth = Math.min(width,minWidth);				maxWidth = Math.max(width,maxWidth);			}			String str = "iwiwiwiau1234";			double width1 = font.createGlyphVector(textArea.getPainter()				.getFontRenderContext(),str).getLogicalBounds()				.getWidth();			double width2 = str.length() * maxWidth;			if(minWidth == maxWidth				&& width1 == width2)			{				Log.log(Log.DEBUG,this,"Using monospaced font optimization: " + font);				returnValue = new Integer(maxWidth);			}			else			{				Log.log(Log.DEBUG,this,"Not using monospaced font optimization: " + font);				Log.log(Log.DEBUG,this,"Minimum width = " + minWidth					+ ", maximum width = " + maxWidth);				returnValue = new Integer(0);			}			fonts.put(font,returnValue);		}		return returnValue.intValue();	} //}}}	//}}}	//{{{ Inner classes	//{{{ PaintLineBackground class	class PaintLineBackground extends TextAreaExtension	{		//{{{ 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();			//{{{ Paint line highlight and collapsed fold highlight			boolean collapsedFold =				(physicalLine < buffer.getLineCount() - 1				&& buffer.isFoldStart(physicalLine)				&& !textArea.displayManager				.isLineVisible(physicalLine + 1));			SyntaxStyle foldLineStyle = null;			if(collapsedFold)			{				int level = buffer.getFoldLevel(physicalLine + 1);				if(buffer.getFoldHandler() instanceof IndentFoldHandler)					level = Math.max(1,level / buffer.getIndentSize());				if(level > 3)					level = 0;				foldLineStyle = TextAreaPainter.this.foldLineStyle[level];			}			int caret = textArea.getCaretPosition();			boolean paintLineHighlight = isLineHighlightEnabled()				&& caret >= start && caret < end				&& textArea.selection.size() == 0;			Color bgColor;			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());			} //}}}			//{{{ Paint token backgrounds			ChunkCache.LineInfo lineInfo = textArea.chunkCache				.getLineInfo(screenLine);			if(lineInfo.chunks != null)			{				float baseLine = y + fm.getHeight()					- fm.getLeading() - fm.getDescent();				Chunk.paintChunkBackgrounds(					lineInfo.chunks,gfx,					textArea.getHorizontalOffset(),					baseLine);			} //}}}		} //}}}	} //}}}	//{{{ 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(textArea.isMultipleSelectionEnabled()				? getMultipleSelectionColor()				: getSelectionColor());			for(int i = textArea.selection.size() - 1; i >= 0; i--)			{				paintSelection(gfx,screenLine,physicalLine,y,					(Selection)textArea.selection.get(i));			}		} //}}}		//{{{ paintSelection() method		private void paintSelection(Graphics2D gfx, int screenLine,			int physicalLine, int y, Selection s)		{			int[] selectionStartAndEnd				= textArea.getSelectionStartAndEnd(				screenLine,physicalLine,s);			if(selectionStartAndEnd == null)				return;			int x1 = selectionStartAndEnd[0];			int x2 = selectionStartAndEnd[1];			gfx.fillRect(x1,y,x2 - x1,fm.getHeight());		} //}}}	} //}}}	//{{{ PaintWrapGuide class	class PaintWrapGuide extends TextAreaExtension	{		public void paintScreenLineRange(Graphics2D gfx, int firstLine,			int lastLine, int[] physicalLines, int[] start,			int[] end, int y, int lineHeight)		{			if(textArea.getDisplayManager().wrapMargin != 0				&& isWrapGuidePainted())			{				gfx.setColor(getWrapGuideColor());				int x = textArea.getHorizontalOffset()					+ textArea.getDisplayManager()					.wrapMargin;				gfx.drawLine(x,y,x,y + (lastLine - firstLine					+ 1) * lineHeight);			}		}		public String getToolTipText(int x, int y)		{			if(textArea.getDisplayManager().wrapMargin != 0 && isWrapGuidePainted())			{				int wrapGuidePos = textArea.getDisplayManager().wrapMargin					+ textArea.getHorizontalOffset();				if(Math.abs(x - wrapGuidePos) < 5)				{					return String.valueOf(textArea.getBuffer()						.getProperty("maxLineLen"));				}			}			return null;		}	} //}}}	//{{{ PaintText class	class PaintText extends TextAreaExtension	{		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			ChunkCache.LineInfo lineInfo = textArea.chunkCache				.getLineInfo(screenLine);			Font defaultFont = getFont();			Color defaultColor = getForeground();			gfx.setFont(defaultFont);			gfx.setColor(defaultColor);			int x = textArea.getHorizontalOffset();			int originalX = x;			float baseLine = y + fm.getHeight()				- fm.getLeading() - fm.getDescent();			if(lineInfo.chunks != null)			{				x += Chunk.paintChunkList(lineInfo.chunks,					gfx,textArea.getHorizontalOffset(),					baseLine,!Debug.DISABLE_GLYPH_VECTOR);			}			Buffer buffer = textArea.getBuffer();			if(!lineInfo.lastSubregion)			{				gfx.setFont(defaultFont);				gfx.setColor(eolMarkerColor);				gfx.drawString(":",Math.max(x,					textArea.getHorizontalOffset()					+ textArea.getDisplayManager().wrapMargin + textArea.charWidth),					baseLine);				x += textArea.charWidth;			}			else if(physicalLine < buffer.getLineCount() - 1				&& buffer.isFoldStart(physicalLine)				&& !textArea.displayManager				.isLineVisible(physicalLine + 1))			{				int level = buffer.getFoldLevel(physicalLine + 1);				if(buffer.getFoldHandler() instanceof IndentFoldHandler)					level = Math.max(1,level / buffer.getIndentSize());				if(level > 3)					level = 0;				SyntaxStyle foldLineStyle = TextAreaPainter.this.foldLineStyle[level];				Font font = foldLineStyle.getFont();				gfx.setFont(font);				gfx.setColor(foldLineStyle.getForegroundColor());				int nextLine;				int nextScreenLine = screenLine + 1;				if(nextScreenLine < textArea.getVisibleLines())				{					nextLine = textArea.chunkCache.getLineInfo(nextScreenLine)						.physicalLine;				}				else				{					nextLine = textArea.displayManager						.getNextVisibleLine(physicalLine);				}				if(nextLine == -1)					nextLine = textArea.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;			}			lineInfo.width = (x - originalX);		}	} //}}}	//{{{ PaintCaret class	class PaintCaret extends TextAreaExtension	{		public void paintValidLine(Graphics2D gfx, int screenLine,			int physicalLine, int start, int end, int y)		{			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(textArea.isOverwriteEnabled())			{				gfx.drawLine(caretX,y + height - 1,					caretX + textArea.charWidth,y + height - 1);			}			else if(blockCaret)				gfx.drawRect(caretX,y,textArea.charWidth - 1,height - 1);			else				gfx.drawLine(caretX,y,caretX,y + height - 1);		}	} //}}}	//}}}}

⌨️ 快捷键说明

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