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

📄 rtextareabase.java~1~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~1~
📖 第 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.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.text.BreakIterator;
import javax.swing.JTextArea;
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;


/**
 * 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.
 * <p>
 *
 * This class is only supposed to be overridden by <code>RTextArea</code>.
 *
 * @author Robert Futrell
 * @version 0.8
 */
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 + -