📄 rtextareabase.java~1~
字号:
/*
* 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 + -