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

📄 jedittextarea.java

📁 Java写的文本编辑器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * JEditTextArea.java - jEdit's text component * Copyright (C) 1999, 2000, 2001 Slava Pestov * Portions copyright (C) 2000 Ollie Rutherfurd * * 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.gjt.sp.jedit.textarea;import javax.swing.border.*;import javax.swing.event.*;import javax.swing.plaf.metal.MetalLookAndFeel;import javax.swing.text.BadLocationException;import javax.swing.text.Element;import javax.swing.text.Segment;import javax.swing.text.Utilities;import javax.swing.undo.*;import javax.swing.*;import java.awt.event.*;import java.awt.*;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.gjt.sp.jedit.gui.*;import org.gjt.sp.jedit.syntax.*;import org.gjt.sp.jedit.*;import org.gjt.sp.util.Log;/** * jEdit's text component. * * @author Slava Pestov * @version $Id: JEditTextArea.java,v 1.2 2001/09/04 06:45:35 spestov Exp $ */public class JEditTextArea extends JComponent{	/**	 * Creates a new JEditTextArea.	 */	public JEditTextArea(View view)	{		enableEvents(AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);		this.view = view;		// Initialize some misc. stuff		selection = new Vector();		renderer = TextRenderer.createTextRenderer();		painter = new TextAreaPainter(this);		gutter = new Gutter(view,this);		documentHandler = new DocumentHandler();		foldHandler = new FoldHandler();		listenerList = new EventListenerList();		caretEvent = new MutableCaretEvent();		bracketLine = bracketPosition = -1;		blink = true;		lineSegment = new Segment();		// Initialize the GUI		setLayout(new ScrollLayout());		add(LEFT,gutter);		add(CENTER,painter);		add(RIGHT,vertical = new JScrollBar(JScrollBar.VERTICAL));		add(BOTTOM,horizontal = new JScrollBar(JScrollBar.HORIZONTAL));		horizontal.setValues(0,0,0,0);		// this ensures that the text area's look is slightly		// more consistent with the rest of the metal l&f.		// while it depends on not-so-well-documented portions		// of Swing, it only affects appearance, so future		// breakage shouldn't matter		if(UIManager.getLookAndFeel() instanceof MetalLookAndFeel)		{			setBorder(new TextAreaBorder());			vertical.putClientProperty("JScrollBar.isFreeStanding",				Boolean.FALSE);			horizontal.putClientProperty("JScrollBar.isFreeStanding",				Boolean.FALSE);			//horizontal.setBorder(null);		}		// Add some event listeners		vertical.addAdjustmentListener(new AdjustHandler());		horizontal.addAdjustmentListener(new AdjustHandler());		painter.addComponentListener(new ComponentHandler());		mouseHandler = new MouseHandler();		painter.addMouseListener(mouseHandler);		painter.addMouseMotionListener(mouseHandler);		addFocusListener(new FocusHandler());		// This doesn't seem very correct, but it fixes a problem		// when setting the initial caret position for a buffer		// (eg, from the recent file list)		focusedComponent = this;	}	/**	 * Returns the object responsible for painting this text area.	 */	public final TextAreaPainter getPainter()	{		return painter;	} 	/**	 * Returns the gutter to the left of the text area or null if the gutter	 * is disabled	 */	public final Gutter getGutter()	{		return gutter;	}	/**	 * 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;		if(buffer != null)			invalidateLine(caretLine);	}	/**	 * Blinks the caret.	 */	public final void blinkCaret()	{		if(caretBlinks)		{			blink = !blink;			invalidateLine(caretLine);		}		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;	}	/**	 * Returns if clicking the middle mouse button pastes the most	 * recent selection (% register).	 */	public final boolean isMiddleMousePasteEnabled()	{		return middleMousePaste;	}	/**	 * Sets if clicking the middle mouse button pastes the most	 * recent selection (% register).	 * @param middleMousePaste A boolean flag	 */	public final void setMiddleMousePasteEnabled(boolean middleMousePaste)	{		this.middleMousePaste = middleMousePaste;	}	/**	 * Updates the state of the scroll bars. This should be called	 * if the number of lines in the buffer changes, or when the	 * size of the text are changes.	 */	public void updateScrollBars()	{		if(vertical != null && visibleLines != 0)		{			// don't display stuff past the end of the buffer if			// we can help it			int lineCount = getVirtualLineCount();			if(lineCount < firstLine + visibleLines)			{				// this will call updateScrollBars(), so				// just return...				int newFirstLine = Math.max(0,lineCount - visibleLines);				if(newFirstLine != firstLine)				{					setFirstLine(newFirstLine);					return;				}			}			vertical.setValues(firstLine,visibleLines,0,lineCount);			vertical.setUnitIncrement(2);			vertical.setBlockIncrement(visibleLines);		}		int width = painter.getWidth();		if(horizontal != null && width != 0)		{			maxHorizontalScrollWidth = 0;			painter.repaint();			horizontal.setUnitIncrement(painter.getFontMetrics()				.charWidth('w'));			horizontal.setBlockIncrement(width / 2);		}	}	/**	 * Returns the line displayed at the text area's origin. This is	 * a virtual, not a physical, line number.	 */	public final int getFirstLine()	{		return firstLine;	}	/**	 * Sets the line displayed at the text area's origin. This is	 * a virtual, not a physical, line number.	 */	public void setFirstLine(int firstLine)	{		if(firstLine == this.firstLine)			return;		_setFirstLine(firstLine);		view.synchroScrollVertical(this,firstLine);	}	public void _setFirstLine(int firstLine)	{		this.firstLine = Math.max(0,firstLine);		physFirstLine = buffer.virtualToPhysical(this.firstLine);		maxHorizontalScrollWidth = 0;		// hack so that if we scroll and the matching bracket		// comes into view, it is highlighted		// 3.2pre9 update: I am commenting this out once again because		// I have changed the location of the documentChanged() call		// in the DocumentHandler, so this is called before the caret		// position is updated, which can be potentially tricky.		//if(bracketPosition == -1)		//	updateBracketHighlight();		if(this.firstLine != vertical.getValue())			updateScrollBars();		painter.repaint();		gutter.repaint();		fireScrollEvent(true);	}	/**	 * Returns the number of lines visible in this text area.	 */	public final int getVisibleLines()	{		return visibleLines;	}	/**	 * 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;		_setHorizontalOffset(horizontalOffset);		view.synchroScrollHorizontal(this,horizontalOffset);	}	public void _setHorizontalOffset(int horizontalOffset)	{		this.horizontalOffset = horizontalOffset;		if(horizontalOffset != horizontal.getValue())			updateScrollBars();		painter.repaint();		fireScrollEvent(false);	}	/**	 * @deprecated Use setFirstLine() and setHorizontalOffset() instead	 */	public boolean setOrigin(int firstLine, int horizontalOffset)	{		setFirstLine(firstLine);		setHorizontalOffset(horizontalOffset);		return true;	}	/**	 * Centers the caret on the screen.	 * @since jEdit 2.7pre2	 */	public void centerCaret()	{		Element map = buffer.getDefaultRootElement();		int gotoLine = buffer.virtualToPhysical(firstLine + visibleLines / 2);		if(gotoLine < 0 || gotoLine >= map.getElementCount())		{			getToolkit().beep();			return;		}		Element element = map.getElement(gotoLine);		setCaretPosition(element.getStartOffset());	}	/**	 * Scrolls up by one line.	 * @since jEdit 2.7pre2	 */	public void scrollUpLine()	{		if(firstLine > 0)			setFirstLine(firstLine-1);		else			getToolkit().beep();	}	/**	 * Scrolls up by one page.	 * @since jEdit 2.7pre2	 */	public void scrollUpPage()	{		if(firstLine > 0)		{			int newFirstLine = firstLine - visibleLines;			setFirstLine(newFirstLine);		}		else		{			getToolkit().beep();		}	}	/**	 * Scrolls down by one line.	 * @since jEdit 2.7pre2	 */	public void scrollDownLine()	{		int numLines = getVirtualLineCount();		if(firstLine + visibleLines < numLines)			setFirstLine(firstLine + 1);		else			getToolkit().beep();	}	/**	 * Scrolls down by one page.	 * @since jEdit 2.7pre2	 */	public void scrollDownPage()	{		int numLines = getVirtualLineCount();		if(firstLine + visibleLines < numLines)		{			int newFirstLine = firstLine + visibleLines;			setFirstLine(newFirstLine + visibleLines < numLines				? newFirstLine : numLines - visibleLines);		}		else		{			getToolkit().beep();		}	}	/**	 * Ensures that the caret is visible by scrolling the text area if	 * necessary.	 * @param doElectricScroll If true, electric scrolling will be performed	 */	public void scrollToCaret(boolean doElectricScroll)	{		if(!buffer.isLineVisible(caretLine))			buffer.expandFoldAt(caretLine,true,this);		int offset = caret - getLineStartOffset(caretLine);		int virtualCaretLine = buffer.physicalToVirtual(caretLine);		// visibleLines == 0 before the component is realized		// we can't do any proper scrolling then, so we have		// this hack...		if(visibleLines == 0)		{			setFirstLine(caretLine - electricScroll);			return;		}		int lineCount = getVirtualLineCount();		int _lastLine = firstLine + visibleLines;		int electricScroll;		if(doElectricScroll && visibleLines > this.electricScroll * 2)			electricScroll = this.electricScroll;		else			electricScroll = 0;		boolean changed = false;		int _firstLine = (firstLine == 0 ? 0 : firstLine + electricScroll);		if(_lastLine >= lineCount - 1)			_lastLine = lineCount - 1;		else			_lastLine -= electricScroll;		if(virtualCaretLine > _firstLine && virtualCaretLine < _lastLine)		{			// vertical scroll position is correct already		}		else if(_firstLine - virtualCaretLine > visibleLines			|| virtualCaretLine - _lastLine > visibleLines)		{			int startLine, endLine;			Selection s = getSelectionAtOffset(caret);			if(s == null)			{				startLine = endLine = virtualCaretLine;			}			else			{				startLine = buffer.physicalToVirtual(s.startLine);				endLine = buffer.physicalToVirtual(s.endLine);			}			if(endLine - startLine <= visibleLines)				firstLine = (startLine + endLine - visibleLines) / 2;			else				firstLine = buffer.physicalToVirtual(caretLine) - visibleLines / 2;			firstLine = Math.min(firstLine,buffer.getVirtualLineCount()				- visibleLines);			firstLine = Math.max(firstLine,0);			changed = true;		}		else if(virtualCaretLine < _firstLine)		{			firstLine = Math.max(0,virtualCaretLine - electricScroll);			changed = true;		}		else if(virtualCaretLine >= _lastLine)		{			firstLine = (virtualCaretLine - visibleLines)				+ electricScroll + 1;			if(firstLine >= getVirtualLineCount() - visibleLines)				firstLine = getVirtualLineCount() - visibleLines;			changed = true;		}		int x = offsetToX(caretLine,offset);		int width = painter.getFontMetrics().charWidth('w');		if(x < 0)		{			horizontalOffset = Math.min(0,horizontalOffset				- x + width + 5);			changed = true;		}		else if(x >= painter.getWidth() - width - 5)		{			horizontalOffset = horizontalOffset +				(painter.getWidth() - x) - width - 5;			changed = true;		}		if(changed)		{			if(firstLine < 0)				firstLine = 0;			physFirstLine = buffer.virtualToPhysical(firstLine);			updateScrollBars();			painter.repaint();			gutter.repaint();			view.synchroScrollVertical(this,firstLine);			view.synchroScrollHorizontal(this,horizontalOffset);			// fire events for both a horizontal and vertical scroll			fireScrollEvent(true);			fireScrollEvent(false);		}	}	/**	 * Converts a line index to a y co-ordinate. This must be a virtual,	 * not a physical, line number.	 * @param line The line	 */	public int lineToY(int line)	{		FontMetrics fm = painter.getFontMetrics();		return (line - firstLine) * fm.getHeight()			- (fm.getLeading() + fm.getDescent());	}	/**	 * Converts a y co-ordinate to a virtual 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(getVirtualLineCount() - 1,			y / height + firstLine));	}	/**	 * Returns the text renderer instance. This method is going away in	 * the next major release, so do not use it.	 * @since jEdit 3.2pre6	 */	public TextRenderer getTextRenderer()	{		return renderer;	}	/**	 * Converts an offset in a line into an x co-ordinate.	 * @param line The line	 * @param offset The offset, from the start of the line	 */	public int offsetToX(int line, int offset)	{		Token tokens = buffer.markTokens(line).getFirstToken();		getLineText(line,lineSegment);		char[] text = lineSegment.array;		int off = lineSegment.offset;		float x = (float)horizontalOffset;		Toolkit toolkit = painter.getToolkit();		Font defaultFont = painter.getFont();		SyntaxStyle[] styles = painter.getStyles();		for(;;)		{			byte id = tokens.id;			if(id == Token.END)				return (int)x;			Font font;			if(id == Token.NULL)

⌨️ 快捷键说明

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