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

📄 jedittextarea.java

📁 jedit中独立出来的语法高亮组件
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * JEditTextArea.java - jEdit's text component * Copyright (C) 1999 Slava Pestov * * You may use and modify this package for any purpose. Redistribution is * permitted, in both source and binary form, provided that this notice * remains intact in all source distributions of this package. */package org.syntax.jedit;import org.syntax.jedit.tokenmarker.*;  import javax.swing.event.*;import javax.swing.text.*;import javax.swing.undo.*;import javax.swing.*;import java.awt.datatransfer.*;import java.awt.event.*;import java.awt.*;import java.util.Enumeration;import java.util.Vector;/** * jEdit's text area component. It is more suited for editing program * source code than JEditorPane, because it drops the unnecessary features * (images, variable-width lines, and so on) and adds a whole bunch of * useful goodies such as: * <ul> * <li>More flexible key binding scheme * <li>Supports macro recorders * <li>Rectangular selection * <li>Bracket highlighting * <li>Syntax highlighting * <li>Command repetition * <li>Block caret can be enabled * </ul> * It is also faster and doesn't have as many problems. It can be used * in other applications; the only other part of jEdit it depends on is * the syntax package.<p> * * To use it in your app, treat it like any other component, for example: * <pre>JEditTextArea ta = new JEditTextArea(); * ta.setTokenMarker(new JavaTokenMarker()); * ta.setText("public class Test {\n" *     + "    public static void main(String[] args) {\n" *     + "        System.out.println(\"Hello World\");\n" *     + "    }\n" *     + "}");</pre> * * @author Slava Pestov * @version $Id: JEditTextArea.java,v 1.36 1999/12/13 03:40:30 sp Exp $ */public class JEditTextArea extends JComponent{	/**	 * Adding components with this name to the text area will place	 * them left of the horizontal scroll bar. In jEdit, the status	 * bar is added this way.	 */	public static String LEFT_OF_SCROLLBAR = "los";	/**	 * Creates a new JEditTextArea with the default settings.	 */	public JEditTextArea()	{		this(TextAreaDefaults.getDefaults());	}	/**	 * Creates a new JEditTextArea with the specified settings.	 * @param defaults The default settings	 */	public JEditTextArea(TextAreaDefaults defaults)	{		// Enable the necessary events		enableEvents(AWTEvent.KEY_EVENT_MASK);		// Initialize some misc. stuff		painter = new TextAreaPainter(this,defaults);		documentHandler = new DocumentHandler();		listenerList = new EventListenerList();		caretEvent = new MutableCaretEvent();		lineSegment = new Segment();		bracketLine = bracketPosition = -1;		blink = true;		// Initialize the GUI		setLayout(new ScrollLayout());		add(CENTER,painter);		add(RIGHT,vertical = new JScrollBar(JScrollBar.VERTICAL));		add(BOTTOM,horizontal = new JScrollBar(JScrollBar.HORIZONTAL));		// Add some event listeners		vertical.addAdjustmentListener(new AdjustHandler());		horizontal.addAdjustmentListener(new AdjustHandler());		painter.addComponentListener(new ComponentHandler());		painter.addMouseListener(new MouseHandler());		painter.addMouseMotionListener(new DragHandler());		addFocusListener(new FocusHandler());		// Load the defaults		setInputHandler(defaults.inputHandler);		setDocument(defaults.document);		editable = defaults.editable;		caretVisible = defaults.caretVisible;		caretBlinks = defaults.caretBlinks;		electricScroll = defaults.electricScroll;		popup = defaults.popup;		// We don't seem to get the initial focus event?		focusedComponent = this;	}	/**	 * Returns if this component can be traversed by pressing	 * the Tab key. This returns false.	 */	public final boolean isManagingFocus()	{		return true;	}	/**	 * Returns the object responsible for painting this text area.	 */	public final TextAreaPainter getPainter()	{		return painter;	}	/**	 * Returns the input handler.	 */	public final InputHandler getInputHandler()	{		return inputHandler;	}	/**	 * Sets the input handler.	 * @param inputHandler The new input handler	 */	public void setInputHandler(InputHandler inputHandler)	{		this.inputHandler = inputHandler;	}	/**	 * Returns true if the caret is blinking, false otherwise.	 */	public final boolean isCaretBlinkEnabled()	{		return caretBlinks;	}	/**	 * Toggles caret blinking.	 * @param caretBlinks True if the caret should blink, false otherwise	 */	public void setCaretBlinkEnabled(boolean caretBlinks)	{		this.caretBlinks = caretBlinks;		if(!caretBlinks)			blink = false;		painter.invalidateSelectedLines();	}	/**	 * Returns true if the caret is visible, false otherwise.	 */	public final boolean isCaretVisible()	{		return (!caretBlinks || blink) && caretVisible;	}	/**	 * Sets if the caret should be visible.	 * @param caretVisible True if the caret should be visible, false	 * otherwise	 */	public void setCaretVisible(boolean caretVisible)	{		this.caretVisible = caretVisible;		blink = true;		painter.invalidateSelectedLines();	}	/**	 * Blinks the caret.	 */	public final void blinkCaret()	{		if(caretBlinks)		{			blink = !blink;			painter.invalidateSelectedLines();		}		else			blink = true;	}	/**	 * Returns the number of lines from the top and button of the	 * text area that are always visible.	 */	public final int getElectricScroll()	{		return electricScroll;	}	/**	 * Sets the number of lines from the top and bottom of the text	 * area that are always visible	 * @param electricScroll The number of lines always visible from	 * the top or bottom	 */	public final void setElectricScroll(int electricScroll)	{		this.electricScroll = electricScroll;	}	/**	 * Updates the state of the scroll bars. This should be called	 * if the number of lines in the document changes, or when the	 * size of the text are changes.	 */	public void updateScrollBars()	{		if(vertical != null && visibleLines != 0)		{			vertical.setValues(firstLine,visibleLines,0,getLineCount());			vertical.setUnitIncrement(2);			vertical.setBlockIncrement(visibleLines);		}		int width = painter.getWidth();		if(horizontal != null && width != 0)		{			horizontal.setValues(-horizontalOffset,width,0,width * 5);			horizontal.setUnitIncrement(painter.getFontMetrics()				.charWidth('w'));			horizontal.setBlockIncrement(width / 2);		}	}	/**	 * Returns the line displayed at the text area's origin.	 */	public final int getFirstLine()	{		return firstLine;	}	/**	 * Sets the line displayed at the text area's origin without	 * updating the scroll bars.	 */	public void setFirstLine(int firstLine)	{		if(firstLine == this.firstLine)			return;		int oldFirstLine = this.firstLine;		this.firstLine = firstLine;		if(firstLine != vertical.getValue())			updateScrollBars();		painter.repaint();	}	/**	 * Returns the number of lines visible in this text area.	 */	public final int getVisibleLines()	{		return visibleLines;	}	/**	 * Recalculates the number of visible lines. This should not	 * be called directly.	 */	public final void recalculateVisibleLines()	{		if(painter == null)			return;		int height = painter.getHeight();		int lineHeight = painter.getFontMetrics().getHeight();		int oldVisibleLines = visibleLines;		visibleLines = height / lineHeight;		updateScrollBars();	}	/**	 * Returns the horizontal offset of drawn lines.	 */	public final int getHorizontalOffset()	{		return horizontalOffset;	}	/**	 * Sets the horizontal offset of drawn lines. This can be used to	 * implement horizontal scrolling.	 * @param horizontalOffset offset The new horizontal offset	 */	public void setHorizontalOffset(int horizontalOffset)	{		if(horizontalOffset == this.horizontalOffset)			return;		this.horizontalOffset = horizontalOffset;		if(horizontalOffset != horizontal.getValue())			updateScrollBars();		painter.repaint();	}	/**	 * A fast way of changing both the first line and horizontal	 * offset.	 * @param firstLine The new first line	 * @param horizontalOffset The new horizontal offset	 * @return True if any of the values were changed, false otherwise	 */	public boolean setOrigin(int firstLine, int horizontalOffset)	{		boolean changed = false;		int oldFirstLine = this.firstLine;		if(horizontalOffset != this.horizontalOffset)		{			this.horizontalOffset = horizontalOffset;			changed = true;		}		if(firstLine != this.firstLine)		{			this.firstLine = firstLine;			changed = true;		}		if(changed)		{			updateScrollBars();			painter.repaint();		}		return changed;	}	/**	 * Ensures that the caret is visible by scrolling the text area if	 * necessary.	 * @return True if scrolling was actually performed, false if the	 * caret was already visible	 */	public boolean scrollToCaret()	{		int line = getCaretLine();		int lineStart = getLineStartOffset(line);		int offset = Math.max(0,Math.min(getLineLength(line) - 1,			getCaretPosition() - lineStart));		return scrollTo(line,offset);	}	/**	 * Ensures that the specified line and offset is visible by scrolling	 * the text area if necessary.	 * @param line The line to scroll to	 * @param offset The offset in the line to scroll to	 * @return True if scrolling was actually performed, false if the	 * line and offset was already visible	 */	public boolean scrollTo(int line, int offset)	{		// visibleLines == 0 before the component is realized		// we can't do any proper scrolling then, so we have		// this hack...		if(visibleLines == 0)		{			setFirstLine(Math.max(0,line - electricScroll));			return true;		}		int newFirstLine = firstLine;		int newHorizontalOffset = horizontalOffset;		if(line < firstLine + electricScroll)		{			newFirstLine = Math.max(0,line - electricScroll);		}		else if(line + electricScroll >= firstLine + visibleLines)		{			newFirstLine = (line - visibleLines) + electricScroll + 1;			if(newFirstLine + visibleLines >= getLineCount())				newFirstLine = getLineCount() - visibleLines;			if(newFirstLine < 0)				newFirstLine = 0;		}		int x = _offsetToX(line,offset);		int width = painter.getFontMetrics().charWidth('w');		if(x < 0)		{			newHorizontalOffset = Math.min(0,horizontalOffset				- x + width + 5);		}		else if(x + width >= painter.getWidth())		{			newHorizontalOffset = horizontalOffset +				(painter.getWidth() - x) - width - 5;		}		return setOrigin(newFirstLine,newHorizontalOffset);	}	/**	 * Converts a line index to a y co-ordinate.	 * @param line The line	 */	public int lineToY(int line)	{		FontMetrics fm = painter.getFontMetrics();		return (line - firstLine) * fm.getHeight()			- (fm.getLeading() + fm.getMaxDescent());	}	/**	 * Converts a y co-ordinate to a line index.	 * @param y The y co-ordinate	 */	public int yToLine(int y)	{		FontMetrics fm = painter.getFontMetrics();		int height = fm.getHeight();		return Math.max(0,Math.min(getLineCount() - 1,			y / height + firstLine));	}	/**	 * Converts an offset in a line into an x co-ordinate. This is a	 * slow version that can be used any time.	 * @param line The line	 * @param offset The offset, from the start of the line	 */	public final int offsetToX(int line, int offset)	{		// don't use cached tokens		painter.currentLineTokens = null;		return _offsetToX(line,offset);	}	/**	 * Converts an offset in a line into an x co-ordinate. This is a	 * fast version that should only be used if no changes were made	 * to the text since the last repaint.	 * @param line The line	 * @param offset The offset, from the start of the line	 */	public int _offsetToX(int line, int offset)	{		TokenMarker tokenMarker = getTokenMarker();		/* Use painter's cached info for speed */		FontMetrics fm = painter.getFontMetrics();		getLineText(line,lineSegment);		int segmentOffset = lineSegment.offset;		int x = horizontalOffset;		/* If syntax coloring is disabled, do simple translation */		if(tokenMarker == null)		{			lineSegment.count = offset;			return x + Utilities.getTabbedTextWidth(lineSegment,				fm,x,painter,0);		}		/* If syntax coloring is enabled, we have to do this because		 * tokens can vary in width */		else		{			Token tokens;			if(painter.currentLineIndex == line				&& painter.currentLineTokens != null)				tokens = painter.currentLineTokens;			else			{				painter.currentLineIndex = line;				tokens = painter.currentLineTokens					= tokenMarker.markTokens(lineSegment,line);			}			Toolkit toolkit = painter.getToolkit();			Font defaultFont = painter.getFont();			SyntaxStyle[] styles = painter.getStyles();			for(;;)			{				byte id = tokens.id;				if(id == Token.END)				{					return x;				}				if(id == Token.NULL)					fm = painter.getFontMetrics();				else					fm = styles[id].getFontMetrics(defaultFont);				int length = tokens.length;				if(offset + segmentOffset < lineSegment.offset + length)				{					lineSegment.count = offset - (lineSegment.offset - segmentOffset);					return x + Utilities.getTabbedTextWidth(						lineSegment,fm,x,painter,0);				}				else				{					lineSegment.count = length;					x += Utilities.getTabbedTextWidth(						lineSegment,fm,x,painter,0);					lineSegment.offset += length;				}				tokens = tokens.next;			}		}	}

⌨️ 快捷键说明

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