📄 rsyntaxtextarea.java~1~
字号:
/*
* 01/27/2004
*
* RSyntaxTextArea.java - An extension of RTextArea that adds
* the ability to syntax highlight certain programming languages.
* Copyright (C) 2004 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.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.event.CaretEvent;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import org.fife.compiler.Parser;
import org.fife.compiler.ParserNotice;
import org.fife.io.DocumentReader;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaUI;
/**
* An extension of <code>RTextArea</code> that adds syntax highlighting
* of certain programming languages to its list of features. Languages
* currently supported include:
* <ul>
* <li>Assembler (X86)</li>
* <li>C</li>
* <li>C++</li>
* <li>CSS</li>
* <li>C#</li>
* <li>Fortran</li>
* <li>HTML</li>
* <li>Java</li>
* <li>JavaScript</li>
* <li>Perl</li>
* <li>SAS</li>
* <li>SQL</li>
* <li>UNIX shell scripts</li>
* <li>Windows batch</li>
* <li>XML files</li>
* </ul>
*
* It is recommended that you use an instance of
* {@link org.fife.ui.rtextarea.RTextScrollPane} instead of a regular
* <code>JScrollPane</code> as this class allows you to add line numbers easily
* to your text area.
*
* @author Robert Futrell
* @version 0.2
*/
public class RSyntaxTextArea extends RTextArea implements SyntaxConstants {
/**
*
*/
private static final long serialVersionUID = -609497005940776636L;
public static final String ANTIALIAS_PROPERTY = "RSyntaxTextArea.antiAlias";
public static final String AUTO_INDENT_PROPERTY = "RSyntaxTextArea.autoIndent";
public static final String BRACKET_MATCHING_PROPERTY = "RSyntaxTextArea.bracketMatching";
public static final String CLEAR_WHITESPACE_LINES_PROPERTY = "RSyntaxTextArea.clearWhitespaceLines";
public static final String FRACTIONAL_FONTMETRICS_PROPERTY = "RSyntaxTextArea.fractionalFontMetrics";
public static final String SYNTAX_SCHEME_PROPERTY = "RSyntaxTextArea.syntaxScheme";
public static final String SYNTAX_STYLE_PROPERTY = "RSyntaxTextArea.syntaxStyle";
public static final String VISIBLE_WHITESPACE_PROPERTY = "RSyntaxTextArea.visibleWhitespace";
private static final Color DEFAULT_BRACKET_MATCH_BG_COLOR = new Color(234,234,255);
private static final Color DEFAULT_BRACKET_MATCH_BORDER_COLOR = new Color(0,0,128);
private static final boolean DEBUG_PARSING = true;
/**
* The syntax style to be highlighting.
*/
private int syntaxStyle;
/**
* The colors used for syntax highlighting.
*/
private SyntaxHighlightingColorScheme colorScheme;
/**
* Handles code templates.
*/
private static CodeTemplateManager codeTemplateManager;
/**
* Whether or not templates are enabled.
*/
private static boolean templatesEnabled;
/**
* The rectangle surrounding the "matched bracket" if bracket matching
* is enabled.
*/
Rectangle match;
/**
* Colors used for the "matched bracket" if bracket matching is
* enabled.
*/
private Color matchedBracketBGColor;
private Color matchedBracketBorderColor;
/**
* Whether or not bracket matching is enabled.
*/
private boolean bracketMatchingEnabled;
/**
* Whether or not auto-indent is on.
*/
private boolean autoIndentEnabled;
/**
* Whether or not lines with nothing but whitespace are "made empty."
*/
private boolean clearWhitespaceLines;
/**
* Whether we are displaying visible whitespace (spaces and tabs).
*/
private boolean whitespaceVisible = false;
/**
* Manages running the parser.
*/
private ParserManager parserManager;
/**
* List of highlights (of errors, warnings, etc.) from the parser.
*/
private List parserNoticeHighlights;
/**
* Painter used to underline errors.
*/
private SquiggleUnderlineHighlightPainter parserErrorHighlightPainter =
new SquiggleUnderlineHighlightPainter(Color.RED);
private int lineHeight; // Height of a line of text; should be the same for default, bold & italic.
private int maxAscent;
public Font getFontForTokenType(int type) {
return colorScheme.syntaxSchemes[type].font;
}
public FontMetrics getFontMetricsForTokenType(int type) {
return colorScheme.syntaxSchemes[type].fontMetrics;
}
public int getMaxAscent() {
return maxAscent;
}
private void refreshFontMetrics(Graphics2D g2d) {
// It is assumed that any rendering hints are already applied to g2d.
for (int i=0; i<colorScheme.syntaxSchemes.length; i++) {
SyntaxScheme ss = colorScheme.syntaxSchemes[i];
if (ss!=null) {
ss.fontMetrics = g2d.getFontMetrics(ss.font);
}
}
if (getLineWrap()==false) {
// HORRIBLE HACK! The un-wrapped view needs to refresh its cached
// longest line information.
((SyntaxView)getUI().getRootView(this).getView(0)).calculateLongestLine();
}
}
private boolean antiAliasEnabled;
private boolean fractionalFontMetricsEnabled;
public void setAntiAliasEnabled(boolean enabled) {
if (antiAliasEnabled!=enabled) {
antiAliasEnabled = enabled;
// We must be connected to a screen resource for our graphics to be
// non-null.
if (isDisplayable())
refreshFontMetrics(getGraphics2D(getGraphics()));
firePropertyChange(ANTIALIAS_PROPERTY, !enabled, enabled);
}
}
public void setFractionalFontMetricsEnabled(boolean enabled) {
if (fractionalFontMetricsEnabled!=enabled) {
fractionalFontMetricsEnabled = enabled;
// We must be connected to a screen resource for our graphics to be
// non-null.
if (isDisplayable())
refreshFontMetrics(getGraphics2D(getGraphics()));
firePropertyChange(FRACTIONAL_FONTMETRICS_PROPERTY,
!enabled, enabled);
}
}
// Need to update the fontmetrics the first time we're displayed!
public void addNotify() {
super.addNotify();
// We know we've just been connected to a screen resource (by definition),
// so initialize our font metrics objects.
refreshFontMetrics(getGraphics2D(getGraphics()));
}
/*****************************************************************************/
/**
* Creates a new <code>RSyntaxTextArea</code> with the following
* properties: no word wrap, INSERT_MODE, Plain white background, tab size
* of 5 spaces, no syntax highlighting, and default caret color,
* selection color, and syntax highlighting scmeme.
*/
public RSyntaxTextArea() {
this(false, INSERT_MODE);
}
/*****************************************************************************/
/**
* Creates a new <code>RSyntaxTextArea</code>.
*
* @param wordWrapEnabled Whether to use word wrap in this text area.
* @param textMode Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
*/
public RSyntaxTextArea(boolean wordWrapEnabled, int textMode) {
// NOTE: The font passed to the super constructor below isn't
// actually used, so we can pass whatever we want (other than null,
// which may cause NPE's in other methods).
super(new Font("monospaced", Font.PLAIN, 13), wordWrapEnabled, textMode);
// Set some RSyntaxTextArea default values.
syntaxStyle = RSyntaxTextArea.NO_SYNTAX_STYLE;
setMatchedBracketBGColor(getDefaultBracketMatchBGColor());
setMatchedBracketBorderColor(getDefaultBracketMatchBorderColor());
setBracketMatchingEnabled(true);
// Set auto-indent releated stuff.
setAutoIndentEnabled(true);
setClearWhitespaceLinesEnabled(true);
}
/*****************************************************************************/
/**
* Removes all highlights in the document from the parser.
*
* @see #refreshParserHighlights
*/
protected void clearParserNoticeHighlights() {
Highlighter h = getHighlighter();
if (h!=null && parserNoticeHighlights!=null) {
int count = parserNoticeHighlights.size();
for (int i=0; i<count; i++)
h.removeHighlight(parserNoticeHighlights.get(i));
parserNoticeHighlights.clear();
}
repaint();
}
/*****************************************************************************/
/**
* Returns the document to use for an <code>RSyntaxTextArea</code>
*
* @return The document.
*/
protected Document createDefaultModel() {
return new RSyntaxDocument(NO_SYNTAX_STYLE);
}
/*****************************************************************************/
/**
* Returns the a real UI to install on this text area.
*
* @return The UI.
*/
protected RTextAreaUI createRTextAreaUI() {
return new RSyntaxTextAreaUI(this);
}
/*****************************************************************************/
/**
* If the caret is on a bracket, this method finds the matching bracket,
* and if it exists, highlights it.
*/
protected final void doBracketMatching() {
// We always need to repaint the "matched bracket" highlight if it
// exists.
if (match!=null)
repaint(match);
// If a matching bracket is found, get its bounds and paint it!
int pos = RSyntaxUtilities.getMatchingBracketPosition(this);
if (pos>-1) {
try {
match = modelToView(pos);
repaint(match);
} catch (BadLocationException ble) {
// Shouldn't happen.
ble.printStackTrace();
}
}
else {
// Set match to null so the old value isn't still repainted.
match = null;
}
}
/*****************************************************************************/
/**
* Notifies all listeners that a caret change has occured.
*
* @param e The caret event.
*/
protected void fireCaretUpdate(CaretEvent e) {
super.fireCaretUpdate(e);
if (bracketMatchingEnabled)
doBracketMatching();
}
/*****************************************************************************/
/**
* Returns whether anti-aliasing is enabled for this text area.
*
* @return Whether anti-aliasing is enabled.
* @see #setAntiAliasEnabled
* @see #getFractionalFontMetricsEnabled
*/
public boolean getAntiAliasEnabled() {
return antiAliasEnabled;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -