📄 parsermanager.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 + -