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

📄 displaymanager.java

📁 开源的java 编辑器源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * DisplayManager.java - Low-level text display * :tabSize=8:indentSize=8:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2001, 2003 Slava Pestov * * 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;//{{{ Importsimport java.awt.Toolkit;import java.util.*;import org.gjt.sp.jedit.buffer.*;import org.gjt.sp.jedit.*;import org.gjt.sp.util.Log;//}}}/** * Manages low-level text display tasks. * @since jEdit 4.2pre1 * @author Slava Pestov * @version $Id: DisplayManager.java,v 1.85 2004/02/23 05:50:12 spestov Exp $ */public class DisplayManager{	//{{{ Static part	public static long scanCount, scannedLines;	//{{{ getDisplayManager() method	static DisplayManager getDisplayManager(Buffer buffer,		JEditTextArea textArea)	{		List l = (List)bufferMap.get(buffer);		DisplayManager dmgr;		if(l == null)		{			l = new LinkedList();			bufferMap.put(buffer,l);		}		Iterator liter = l.iterator();		while(liter.hasNext())		{			dmgr = (DisplayManager)liter.next();			if(!dmgr.inUse && dmgr.textArea == textArea)			{				dmgr.inUse = true;				return dmgr;			}		}		// if we got here, no unused display manager in list		dmgr = new DisplayManager(buffer,textArea);		dmgr.inUse = true;		l.add(dmgr);		return dmgr;	} //}}}	//{{{ releaseDisplayManager() method	static void releaseDisplayManager(DisplayManager dmgr)	{		dmgr.inUse = false;	} //}}}	//{{{ bufferClosed() method	public static void bufferClosed(Buffer buffer)	{		bufferMap.remove(buffer);	} //}}}	//{{{ textAreaDisposed() method	static void textAreaDisposed(JEditTextArea textArea)	{		Iterator biter = bufferMap.values().iterator();		while(biter.hasNext())		{			List l = (List)biter.next();			Iterator liter = l.iterator();			while(liter.hasNext())			{				DisplayManager dmgr = (DisplayManager)					liter.next();				if(dmgr.textArea == textArea)				{					dmgr.dispose();					liter.remove();				}			}		}	} //}}}	//{{{ _notifyScreenLineChanges() method	/* static void _notifyScreenLineChanges(Buffer buffer)	{		Iterator iter = ((List)bufferMap.get(buffer)).iterator();		while(iter.hasNext())		{			((DisplayManager)iter.next())._notifyScreenLineChanges();		}	} */ //}}}	private static Map bufferMap = new HashMap();	//}}}	//{{{ isLineVisible() method	/**	 * Returns if the specified line is visible.	 * @param line A physical line index	 * @since jEdit 4.2pre1	 */	public final boolean isLineVisible(int line)	{		return fvmget(line) % 2 == 0;	} //}}}	//{{{ getFirstVisibleLine() method	/**	 * Returns the physical line number of the first visible line.	 * @since jEdit 4.2pre1	 */	public int getFirstVisibleLine()	{		return fvm[0];	} //}}}	//{{{ getLastVisibleLine() method	/**	 * Returns the physical line number of the last visible line.	 * @since jEdit 4.2pre1	 */	public int getLastVisibleLine()	{		return fvm[fvmcount - 1] - 1;	} //}}}	//{{{ getNextVisibleLine() method	/**	 * Returns the next visible line after the specified line index.	 * @param line A physical line index	 * @since jEdit 4.0pre1	 */	public int getNextVisibleLine(int line)	{		int index = fvmget(line);		/* in collapsed range */		if(index % 2 != 0)		{			/* beyond last visible line */			if(fvmcount == index + 1)				return - 1;			/* start of next expanded range */			else				return fvm[index + 1];		}		/* last in expanded range */		else if(line == fvm[index + 1] - 1)		{			/* equal to last visible line */			if(fvmcount == index + 2)				return -1;			/* start of next expanded range */			else				return fvm[index + 2];		}		/* next in expanded range */		else			return line + 1;	} //}}}	//{{{ getPrevVisibleLine() method	/**	 * Returns the previous visible line before the specified line index.	 * @param line A physical line index	 * @since jEdit 4.0pre1	 */	public int getPrevVisibleLine(int line)	{		int index = fvmget(line);		/* before first visible line */		if(index == -1)			return -1;		/* in collapsed range */		else if(index % 2 == 1)		{			/* end of prev expanded range */			return fvm[index] - 1;		}		/* first in expanded range */		else if(line == fvm[index])		{			/* equal to first visible line */			if(index == 0)				return -1;			/* end of prev expanded range */			else				return fvm[index - 1] - 1;		}		/* prev in expanded range */		else			return line - 1;	} //}}}	//{{{ getScreenLineCount() method	public final int getScreenLineCount(int line)	{		if(lineMgr.isScreenLineCountValid(line))			return lineMgr.getScreenLineCount(line);		else		{			int newCount = textArea.chunkCache				.getLineSubregionCount(line);			setScreenLineCount(line,newCount);			return newCount;		}	} //}}}	//{{{ getScrollLineCount() method	public final int getScrollLineCount()	{		return scrollLineCount.scrollLine;	} //}}}	//{{{ collapseFold() method	/**	 * Collapses the fold at the specified physical line index.	 * @param line A physical line index	 * @since jEdit 4.2pre1	 */	public void collapseFold(int line)	{		int lineCount = buffer.getLineCount();		int start = 0;		int end = lineCount - 1;		// if the caret is on a collapsed fold, collapse the		// parent fold		if(line != 0			&& line != buffer.getLineCount() - 1			&& buffer.isFoldStart(line)			&& !isLineVisible(line + 1))		{			line--;		}		int initialFoldLevel = buffer.getFoldLevel(line);		//{{{ Find fold start and end...		if(line != lineCount - 1			&& buffer.getFoldLevel(line + 1) > initialFoldLevel)		{			// this line is the start of a fold			start = line + 1;			for(int i = line + 1; i < lineCount; i++)			{				if(buffer.getFoldLevel(i) <= initialFoldLevel)				{					end = i - 1;					break;				}			}		}		else		{			boolean ok = false;			// scan backwards looking for the start			for(int i = line - 1; i >= 0; i--)			{				if(buffer.getFoldLevel(i) < initialFoldLevel)				{					start = i + 1;					ok = true;					break;				}			}			if(!ok)			{				// no folds in buffer				return;			}			for(int i = line + 1; i < lineCount; i++)			{				if(buffer.getFoldLevel(i) < initialFoldLevel)				{					end = i - 1;					break;				}			}		} //}}}		// Collapse the fold...		hideLineRange(start,end);		_notifyScreenLineChanges();		textArea.foldStructureChanged();	} //}}}	//{{{ expandFold() method	/**	 * Expands the fold at the specified physical line index.	 * @param line A physical line index	 * @param fully If true, all subfolds will also be expanded	 * @since jEdit 4.2pre1	 */	public int expandFold(int line, boolean fully)	{		// the first sub-fold. used by JEditTextArea.expandFold().		int returnValue = -1;		int lineCount = buffer.getLineCount();		int start = 0;		int end = lineCount - 1;		int initialFoldLevel = buffer.getFoldLevel(line);		//{{{ Find fold start and fold end...		if(line != lineCount - 1			&& isLineVisible(line)			&& !isLineVisible(line + 1)			&& buffer.getFoldLevel(line + 1) > initialFoldLevel)		{			// this line is the start of a fold			int index = fvmget(line + 1);			if(index == -1)			{				expandAllFolds();				return -1;			}			start = fvm[index];			if(index != fvmcount - 1)				end = fvm[index + 1] - 1;			else			{				start = line + 1;				for(int i = line + 1; i < lineCount; i++)				{					if(/* isLineVisible(i) && */						buffer.getFoldLevel(i) <= initialFoldLevel)					{						end = i - 1;						break;					}				}			}		}		else		{			int index = fvmget(line);			if(index == -1)			{				expandAllFolds();				return -1;			}			start = fvm[index];			if(index != fvmcount - 1)				end = fvm[index + 1] - 1;			else			{				for(int i = line + 1; i < lineCount; i++)				{					//XXX					if((isLineVisible(i) &&						buffer.getFoldLevel(i) < initialFoldLevel)						|| i == getLastVisibleLine())					{						end = i - 1;						break;					}				}			}		} //}}}		//{{{ Expand the fold...		if(fully)		{			showLineRange(start,end);		}		else		{			// we need a different value of initialFoldLevel here!			initialFoldLevel = buffer.getFoldLevel(start);			int firstVisible = start;			for(int i = start; i <= end; i++)			{				if(buffer.getFoldLevel(i) > initialFoldLevel)				{					if(returnValue == -1						&& i != 0						&& buffer.isFoldStart(i - 1))					{						returnValue = i - 1;					}					if(firstVisible != i)					{						showLineRange(firstVisible,i - 1);					}					firstVisible = i + 1;				}			}			if(firstVisible != end + 1)				showLineRange(firstVisible,end);			if(!isLineVisible(line))			{				// this is a hack, and really needs to be done better.				expandFold(line,false);				return returnValue;			}		} //}}}		_notifyScreenLineChanges();		textArea.foldStructureChanged();		return returnValue;	} //}}}	//{{{ expandAllFolds() method	/**	 * Expands all folds.	 * @since jEdit 4.2pre1	 */	public void expandAllFolds()	{		showLineRange(0,buffer.getLineCount() - 1);		_notifyScreenLineChanges();		textArea.foldStructureChanged();	} //}}}	//{{{ expandFolds() method	/**	 * This method should only be called from <code>actions.xml</code>.	 * @since jEdit 4.2pre1	 */	public void expandFolds(char digit)	{		if(digit < '1' || digit > '9')		{			Toolkit.getDefaultToolkit().beep();			return;		}		else			expandFolds((int)(digit - '1') + 1);	} //}}}	//{{{ expandFolds() method	/**	 * Expands all folds with the specified fold level.	 * @param foldLevel The fold level	 * @since jEdit 4.2pre1	 */	public void expandFolds(int foldLevel)	{		if(buffer.getFoldHandler() instanceof IndentFoldHandler)			foldLevel = (foldLevel - 1) * buffer.getIndentSize() + 1;		showLineRange(0,buffer.getLineCount() - 1);		/* this ensures that the first line is always visible */		boolean seenVisibleLine = false;		int firstInvisible = 0;		for(int i = 0; i < buffer.getLineCount(); i++)		{			if(!seenVisibleLine || buffer.getFoldLevel(i) < foldLevel)			{				if(firstInvisible != i)				{					hideLineRange(firstInvisible,						i - 1);				}				firstInvisible = i + 1;				seenVisibleLine = true;			}		}		if(firstInvisible != buffer.getLineCount())			hideLineRange(firstInvisible,buffer.getLineCount() - 1);		_notifyScreenLineChanges();		textArea.foldStructureChanged();	} //}}}	//{{{ narrow() method	/**	 * Narrows the visible portion of the buffer to the specified	 * line range.	 * @param start The first line	 * @param end The last line	 * @since jEdit 4.2pre1	 */	public void narrow(int start, int end)	{		if(start > end || start < 0 || end >= buffer.getLineCount())			throw new ArrayIndexOutOfBoundsException(start + ", " + end);		if(start < getFirstVisibleLine() || end > getLastVisibleLine())			expandAllFolds();		if(start != 0)			hideLineRange(0,start - 1);		if(end != buffer.getLineCount() - 1)			hideLineRange(end + 1,buffer.getLineCount() - 1);		// if we narrowed to a single collapsed fold		if(start != buffer.getLineCount() - 1			&& !isLineVisible(start + 1))			expandFold(start,false);		// Hack... need a more direct way of obtaining a view?		// JEditTextArea.getView() method?		GUIUtilities.getView(textArea).getStatus().setMessageAndClear(			jEdit.getProperty("view.status.narrow"));		_notifyScreenLineChanges();		textArea.foldStructureChanged();	} //}}}	//{{{ Package-private members	boolean softWrap;	int wrapMargin;	FirstLine firstLine;	ScrollLineCount scrollLineCount;	//{{{ init() method	void init()	{		if(!initialized)		{			initialized = true;			fvm = new int[2];			if(buffer.isLoaded())				bufferChangeHandler.foldHandlerChanged(buffer);			else				fvmreset();			_notifyScreenLineChanges();		}		else		{			updateWrapSettings();			_notifyScreenLineChanges();			textArea.updateScrollBars();			textArea.recalculateLastPhysicalLine();		}	} //}}}	//{{{ setScreenLineCount() method	/**	 * Sets the number of screen lines that the specified physical line	 * is split into.	 * @since jEdit 4.2pre1	 */	void setScreenLineCount(int line, int count)	{		int oldCount = lineMgr.getScreenLineCount(line);		// still have to call this even if it equals the		// old one so that the offset manager sets the		// validity flag!		lineMgr.setScreenLineCount(line,count);		// this notifies each display manager editing this		// buffer of the screen line count change		if(count != oldCount)		{			Iterator iter = ((List)bufferMap.get(buffer))				.iterator();			while(iter.hasNext())			{				((DisplayManager)iter.next())._setScreenLineCount(					line,oldCount,count);			}		}	} //}}}	//{{{ updateWrapSettings() method	void updateWrapSettings()	{		String wrap = buffer.getStringProperty("wrap");		softWrap = wrap.equals("soft");		if(textArea.maxLineLen <= 0)		{			softWrap = false;			wrapMargin = 0;		}		else		{			// stupidity			char[] foo = new char[textArea.maxLineLen];			for(int i = 0; i < foo.length; i++)			{				foo[i] = ' ';			}			TextAreaPainter painter = textArea.getPainter();			wrapMargin = (int)painter.getFont().getStringBounds(				foo,0,foo.length,				painter.getFontRenderContext())				.getWidth();		}	} //}}}	//{{{ _notifyScreenLineChanges() method	void _notifyScreenLineChanges()	{		if(Debug.SCROLL_DEBUG)			Log.log(Log.DEBUG,this,"_notifyScreenLineChanges()");		// when the text area switches to us, it will do		// a reset anyway

⌨️ 快捷键说明

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