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

📄 rsyntaxtextarea.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 *
 * 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.
   *

⌨️ 快捷键说明

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