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

📄 rtextareabase.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * 04/07/2005
 *
 * RTextAreaBase.java - The base class for an RTextArea.
 * 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.rtextarea;

import java.awt.*;
import java.awt.event.*;
import java.text.BreakIterator;
import javax.swing.event.CaretEvent;
import javax.swing.plaf.TextUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.JTextArea;

/**
 * This is the base class for <code>RTextArea</code>; basically it's just an
     * extension of <code>javax.swing.JTextArea</code> adding a bunch of properties.
 */
abstract class RTextAreaBase
    extends JTextArea {

  public static final String CURRENT_LINE_HIGHLIGHT_PROPERTY =
      "RTextArea.currentLineHighlight";
  public static final String CURRENT_LINE_HIGHLIGHT_COLOR_PROPERTY =
      "RTextArea.currentLineHighlightColor";
  public static final String CURRENT_LINE_HIGHLIGHT_FADE_PROPERTY =
      "RTextArea.currentLineHighlightFade";
  public static final String ROUNDED_SELECTION_PROPERTY =
      "RTextMainPanel.roundedSelection";

  private boolean tabsEmulatedWithSpaces; // If true, tabs will be expanded to spaces.

  private boolean highlightCurrentLine; // If true, the current line is highlighted.
  private Color currentLineColor; // The color used to highlight the current line.
  private boolean marginLineEnabled; // If true, paint a "margin line."
  private Color marginLineColor; // The color used to paint the margin line.
  protected int marginLineX; // The x-location of the margin line.
  protected int marginSizeInChars; // How many 'm' widths the margin line is over.
  private boolean fadeCurrentLineHighlight; // "Fade effect" for current line highlight.
  private boolean roundedSelectionEdges;
  private int previousCaretY;
  int currentCaretY; // Used to know when to rehighlight current line.

  private BackgroundPainterStrategy backgroundPainter; // Paints the background.

  private RTAMouseListener mouseListener;

  private static final Color DEFAULT_CARET_COLOR = new Color(255, 51, 51);
  private static final Color DEFAULT_SELECTION_COLOR = new Color(200, 200, 255);
  private static final Color DEFAULT_CURRENT_LINE_HIGHLIGHT_COLOR = new Color(
      255, 255, 170);
  private static final Color DEFAULT_MARGIN_LINE_COLOR = new Color(255, 224,
      224);
  private static final int DEFAULT_TAB_SIZE = 5;
  private static final int DEFAULT_MARGIN_LINE_POSITION = 80;

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

  /**
   * Constructor.
   *
   * @param font The font to use in this text area.
   * @param wordWrapEnabled Whether or not to use word wrap.
   */
  public RTextAreaBase(Font font, boolean wordWrapEnabled) {

    // Sets the UI.  Note that setUI() is overridden in RTextArea to only
    // update the popup menu; this method must be called to set the real
    // UI.  This is done because the look and feel of an RTextArea is
    // independent of the installed Java look and feels.
    setRTextAreaUI(createRTextAreaUI());

    // So we get notified when the component is resized.
    enableEvents(AWTEvent.COMPONENT_EVENT_MASK);

    // Defaults for various properties.
    setCurrentLineHighlightEnabled(true);
    setCurrentLineHighlightColor(getDefaultCurrentLineHighlightColor());
    setMarginLineEnabled(false);
    setMarginLineColor(getDefaultMarginLineColor());
    setMarginLinePosition(getDefaultMarginLinePosition());
    setBackgroundObject(Color.WHITE);
    setWrapStyleWord(true); // We only support wrapping at word boundaries.
    setSelectionColor(getDefaultSelectionColor());
    setTabSize(5);
    setForeground(Color.BLACK);
    setTabsEmulated(false);

    // Set properties the user passed in.
    setFont(font);
    setLineWrap(wordWrapEnabled);

    // Stuff needed by the caret listener below.
    previousCaretY = currentCaretY = 0;
    // Need this because modelToView() is called from RTextArea's
    // constructor code and we need this component to be sized for it
    // (still true???  22nov2004).  Also, if its width is too small
    // (i.e., "1"), then RSyntaxTextArea's WrappedSyntaxView goes into a
    // infinite loop trying to fit text into the 1-pixel width (although
    // it shouldn't, but a plausable width will make its computations go
    // much quicker)...
    setSize(new Dimension(300, 300));

    // Stuff to highlight the current line.
    mouseListener = createMouseListener();
    // Also acts as a focus listener so we can update our shared actions
    // (cut, copy, etc. on the popup menu).
    addFocusListener(mouseListener);
    addCurrentLineHighlightListeners();

  }

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

  /**
   * Adds listeners that listen for changes to the current line, so we can
   * update our "current line highlight."  This is needed only because of an
   * apparent difference between the JRE 1.4.2 and 1.5.0 (needed on 1.4.2,
   * not needed on 1.5.0).
   */
  protected void addCurrentLineHighlightListeners() {
    boolean add = true;
    MouseMotionListener[] mouseMotionListeners = getMouseMotionListeners();
    for (int i = 0; i < mouseMotionListeners.length; i++) {
      if (mouseMotionListeners[i] == mouseListener) {
        add = false;
        break;
      }
    }
    if (add == true) {
      //System.err.println("Adding mouse motion listener!");
      addMouseMotionListener(mouseListener);
    }
    MouseListener[] mouseListeners = getMouseListeners();
    for (int i = 0; i < mouseListeners.length; i++) {
      if (mouseListeners[i] == mouseListener) {
        add = false;
        break;
      }
    }
    if (add == true) {
      //System.err.println("Adding mouse listener!");
      addMouseListener(mouseListener);
    }
  }

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

  /**
   * Converts all instances of a number of spaces equal to a tab size
   * into a tab in this text area.
   *
   * @see #convertTabsToSpaces
   * @see #getTabsEmulated
   * @see #setTabsEmulated
   */
  public void convertSpacesToTabs() {

    // FIXME:  This is inefficient and will yield an OutOfMemoryError if
    // done on a large document.  We should scan 1 line at a time and
    // replace; it'll be slower but safer.

    int caretPosition = getCaretPosition();
    int tabSize = getTabSize();
    String tabInSpaces = "";
    for (int i = 0; i < tabSize; i++) {
      tabInSpaces += " ";
    }
    String text = getText();
    setText(text.replaceAll(tabInSpaces, "\t"));
    int newDocumentLength = getDocument().getLength();

    // Place the caret back in its proper position.
    if (caretPosition < newDocumentLength) {
      setCaretPosition(caretPosition);
    }
    else {
      setCaretPosition(newDocumentLength - 1);

    }
  }

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

  /**
   * Converts all instances of a tab into a number of spaces equivalent
   * to a tab in this text area.
   *
   * @see #convertSpacesToTabs
   * @see #getTabsEmulated
   * @see #setTabsEmulated
   */
  public void convertTabsToSpaces() {

    // FIXME:  This is inefficient and will yield an OutOfMemoryError if
    // done on a large document.  We should scan 1 line at a time and
    // replace; it'll be slower but safer.

    int caretPosition = getCaretPosition();
    int tabSize = getTabSize();
    String tabInSpaces = "";
    for (int i = 0; i < tabSize; i++) {
      tabInSpaces += " ";
    }
    String text = getText();
    setText(text.replaceAll("\t", tabInSpaces));

    // Put caret back at same place in document.
    setCaretPosition(caretPosition);

  }

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

  /**
   * Returns the caret event/mouse listener for <code>RTextArea</code>s.
   *
   * @return The caret event/mouse listener.
   */
  protected abstract RTAMouseListener createMouseListener();

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

  /**
   * Returns the a real UI to install on this text component.  Subclasses
   * can override this method to return an extended version of
   * <code>RTextAreaUI</code>.
   *
   * @return The UI.
   */
  protected abstract RTextAreaUI createRTextAreaUI();

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

  /**
   * Forces the current line highlight to be repainted.  This hack is
   * necessary for those situations when the view (appearance) changes
   * but the caret's location hasn't (and thus the current line highlight
   * coordinates won't get changed).  Examples of this are when
   * word wrap is toggled and when syntax styles are changed in an
   * <code>RSyntaxTextArea</code>.
   */
  protected void forceCurrentLineHighlightRepaint() {
    // Check isShowing() to prevent BadLocationException
    // in constructor if linewrap is set to true.
    if (isShowing()) {
      // Changing previousCaretY makes us sure to get a repaint.
      previousCaretY = -1;
      // Trick it into checking for the need to repaint by firing
      // a false caret event.
      fireCaretUpdate(mouseListener);
    }
  }

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

  /**
   * Returns the <code>java.awt.Color</code> used as the background color for
   * this text area.  If a <code>java.awt.Image</code> image is currently
   * being used instead, <code>null</code> is returned.
   *
   * @return The current background color, or <code>null</code> if an image
   *         is currently the background.
   */
  public final Color getBackground() {
    Object bg = getBackgroundObject();
    return (bg instanceof Color) ? (Color) bg : null;
  }

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

  /**
   * Returns the image currently used for the background.
   * If the current background is currently a <code>java.awt.Color</code> and
   * not a <code>java.awt.Image</code>, then <code>null</code> is returned.
   *
   * @return A <code>java.awt.Image</code> used for the background, or
   *         <code>null</code> if the background is not an image.
   * @see #setBackgroundImage
   */
  public final Image getBackgroundImage() {
    Object bg = getBackgroundObject();
    return (bg instanceof Image) ? (Image) bg : null;
  }

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

  /**
   * Returns the <code>Object</code> representing the background for all
   * documents in this tabbed pane; either a <code>java.awt.Color</code> or a
   * <code>java.lang.Image</code> containing the image used as the background
   * for this text area.
   *
   * @return The <code>Object</code> used for the background.
   * @see #setBackgroundObject(Object newBackground)
   */
  public final Object getBackgroundObject() {
    if (backgroundPainter == null) {
      return null;
    }
    return (backgroundPainter instanceof ImageBackgroundPainterStrategy) ?
        (Object) ( (ImageBackgroundPainterStrategy) backgroundPainter).
        getMasterImage() :
        (Object) ( (ColorBackgroundPainterStrategy) backgroundPainter).
        getColor();
  }

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

  /**
   * Gets the line number that the caret is on.
   *
   * @return The zero-based line number that the caret is on.
   */
  public final int getCaretLineNumber() {
    try {
      return getLineOfOffset(getCaretPosition());
    }
    catch (BadLocationException ble) {
      /* Will never happen. */
      return 0;
    }
  }

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

  /**
   * Gets the position from the beginning of the current line that the caret
   * is on.
   *
   * @return The zero-based position from the beginning of the current line
   *         that the caret is on.
   */
  public final int getCaretOffsetFromLineStart() {
    try {
      int pos = getCaretPosition();
      return pos - getLineStartOffset(getLineOfOffset(pos));
    }
    catch (BadLocationException ble) {
      /* Will never happen. */
      return 0;
    }
  }

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

  /**
   * Returns the color being used to highlight the current line.  Note that
   * if highlighting the current line is turned off, you will not be seeing
   * this highlight.
   *
   * @return The color being used to highlight the current line.
   * @see #isCurrentLineHighlightEnabled
   * @see #setCurrentLineHighlightEnabled
   * @see #setCurrentLineHighlightColor
   */
  public Color getCurrentLineHighlightColor() {
    return currentLineColor;
  }

⌨️ 快捷键说明

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