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

📄 parsermanager.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
字号:
/*
 * 09/26/2005
 *
 * ParserManager.java - Manages the parsing of an RSyntaxTextArea's document,
 * if necessary.
 * Copyright (C) 2005 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * 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.fife.ui.rsyntaxtextarea;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.ToolTipManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Highlighter;

import org.fife.compiler.Parser;
import org.fife.io.DocumentReader;


/**
 * Manages running a parser object for an <code>RSyntaxTextArea</code>.
 *
 * @author Robert Futrell
 * @version 0.1
 */
class ParserManager implements ActionListener, DocumentListener {

	private RSyntaxTextArea textArea;
	private Parser parser;
	private Timer timer;

	private boolean needsReparsing;
	private boolean wait;

	private static final boolean DEBUG_PARSING	= true;


/*****************************************************************************/


	/**
	 * Constructor.
	 *
	 * @param textArea The text area whose document the parser will be
	 *        parsing.
	 */
	public ParserManager(RSyntaxTextArea textArea) {
		this.textArea = textArea;
		ToolTipManager.sharedInstance().registerComponent(textArea);
		textArea.getDocument().addDocumentListener(this);
	}


/*****************************************************************************/


	/**
	 * Called when the timer fires.  This method is run in the EDT, but we
	 * need the parsing to be done outside of it for performance.
	 *
	 * @param e The action event.
	 */
	public void actionPerformed(ActionEvent e) {

		if (!needsReparsing) {
			if (DEBUG_PARSING)
				System.err.println("Parsing skipped; not needed");
			return;
		}

		if (wait) {
			if (DEBUG_PARSING)
				System.err.println("Waiting until next time...");
			wait = false;
			return;
		}

		// Do parsing outside of the EDT for performance...
		new Thread(new Runnable() {

			public void run() {

				long begin = 0;
				if (DEBUG_PARSING)
					begin = System.currentTimeMillis();

				DocumentReader r =
						new DocumentReader(textArea.getDocument());
				parser.parse(r);
				needsReparsing = false;
				r.close();

				if (DEBUG_PARSING) {
					float time = (System.currentTimeMillis()-begin)/1000f;
					System.err.println("Parsing took: "+time+" seconds");
				}

				// But update the GUI on the EDT.
				SwingUtilities.invokeLater(new UpdateTextAreaThread());

			}

		}).start();

	}


/*****************************************************************************/


	/**
	 * Called when the document is modified.
	 *
	 * @param e The document event.
	 */
	public void changedUpdate(DocumentEvent e) {
		handleDocumentEvent(e);
	}


/*****************************************************************************/


	/**
	 * Returns the parser.
	 *
	 * @return The parser.
	 * @see #setParser
	 */
	public Parser getParser() {
		return parser;
	}


/*****************************************************************************/


	/**
	 * Returns the tooltip to display for a mouse event at the given
	 * location.  This method is overridden to give a registered parser a
	 * chance to display a tooltip (such as an error description when the
	 * mouse is over an error highlight).
	 *
	 * @param e The mouse event.
	 */
	public String getToolTipText(MouseEvent e) {
		try {
			int pos = textArea.viewToModel(e.getPoint());
			Highlighter.Highlight[] highlights = textArea.getHighlighter().
												getHighlights();
			for (int i=0; i<highlights.length; i++) {
				Highlighter.Highlight h = highlights[i];
				//if (h instanceof ParserNoticeHighlight) {
				//	ParserNoticeHighlight pnh = (ParserNoticeHighlight)h;
					int start = h.getStartOffset();
					int end = h.getEndOffset();
					if (start<=pos && end>=pos) {
						//return pnh.getMessage();
						return textArea.getText(start, end-start);
					}
				//}
			}
		} catch (BadLocationException ble) {
			ble.printStackTrace();	// Should never happen.
		}
		return null;
	}


/*****************************************************************************/


	/**
	 * Called when the document is modified.
	 *
	 * @param e The document event.
	 */
	public void handleDocumentEvent(DocumentEvent e) {
		if (!needsReparsing) {
			needsReparsing = true;
		}
		else {
			// This is an "elaborate" scheme to keep from having to call
			// restart() on the timer every time the user modifies the
			// document before a parsing occurs.  If thread-safety issues
			// arise, this may have to be changed.
			wait = true;
		}
	}


/*****************************************************************************/


	/**
	 * Called when the document is modified.
	 *
	 * @param e The document event.
	 */
	public void insertUpdate(DocumentEvent e) {
		handleDocumentEvent(e);
	}


/*****************************************************************************/


	/**
	 * Called when the document is modified.
	 *
	 * @param e The document event.
	 */
	public void removeUpdate(DocumentEvent e) {
		handleDocumentEvent(e);
	}


/*****************************************************************************/


	/**
	 * Sets the parser.
	 *
	 * @param parser The new parser.
	 * @see #getParser
	 */
	public void setParser(Parser parser) {

		// Clean up old timer, if necessary.
		if (timer!=null) {
			timer.stop();
			timer.removeActionListener(this);
			timer = null;
		}

		// Set the new parser.
		this.parser = parser;

		// Set up timer, if necessary.
		if (parser!=null) {
			needsReparsing = true;
			timer = new Timer(5000, this);
			timer.start();
		}

	}


/*****************************************************************************/


	/**
	 * Terminates the timer used to schedule parsing.  This method is called
	 * by <code>RSyntaxTextArea</code> when it is being removed from a GUI
	 * (via <code>removeNotify()</code>) to "clean up."
	 */
	public void stopParsing() {
		textArea.getDocument().removeDocumentListener(this);
		ToolTipManager.sharedInstance().unregisterComponent(textArea);
		setParser(null);
	}


/*****************************************************************************/
/*********************** INNER CLASSES ***************************************/
/*****************************************************************************/


	/**
	 * Notifies the <code>RSyntaxTextArea</code> that it needs to update
	 * its parser highlights.
	 */
	class UpdateTextAreaThread extends Thread {

		public void run() {
			textArea.refreshParserNoticeHighlights(
									parser.getNoticeIterator());
		}

	}


/*****************************************************************************/

}

⌨️ 快捷键说明

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