📄 rtextareaui.java
字号:
/*
* RTextAreaUI.java - UI used by instances of RTextArea.
*/
package org.fife.ui.rtextarea;
import java.beans.PropertyChangeEvent;
import java.awt.*;
import java.awt.dnd.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import java.util.TooManyListenersException;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.*;
import javax.swing.plaf.*;
/**
* The UI used by instances of <code>RTextArea</code>. This UI takes into
* account all of the "extras" involved in an <code>RTextArea</code>, including
* having a special caret (for insert and overwrite), background images,
* highlighting the current line, etc.
*/
public class RTextAreaUI
extends TextUI
implements ViewFactory {
private static final String RTEXTAREA_KEYMAP_NAME = "RTextAreaKeymap";
private static final String SHARED_ACTION_MAP_NAME = "RTextAreaUI.actionMap";
private static final String SHARED_INPUT_MAP_NAME = "RTextAreaUI.inputMap";
protected RTextArea textArea; // The text area for which we are the UI.
RTARootView rootView; // Our root view.
protected boolean painted;
private static final EditorKit defaultKit = new RTextAreaEditorKit();
private static final Position.Bias[] discardBias = new Position.Bias[1];
// Listeners.
private TextDragGestureRecognizer defaultDragRecognizer = new
TextDragGestureRecognizer();
private RTAUpdateHandler updateHandler = new RTAUpdateHandler(this);
private static final RTATextTransferHandler transferHandler = new
RTATextTransferHandler();
static RTADropTargetListener dropTargetListener = null;
/*****************************************************************************/
/**
* Creates a UI for an RTextArea.
*
* @param rTextArea A text area.
* @return The UI.
*/
public static ComponentUI createUI(JComponent rTextArea) {
return new RTextAreaUI(rTextArea);
}
/*****************************************************************************/
/**
* Constructor.
*
* @param rTextArea An instance of <code>RTextArea</code>.
* @throws IllegalArgumentException If <code>rTextArea</code> is not an
* instance of <code>RTextArea</code>.
*/
public RTextAreaUI(JComponent rTextArea) {
super();
if (! (rTextArea instanceof RTextArea)) {
throw new IllegalArgumentException("RTextAreaUI is for " +
"instances of RTextArea only!");
}
}
/*****************************************************************************/
/**
* Creates the view for an element. Returns a WrappedPlainView or
* PlainView.
*
* @param elem The element.
* @return The view.
*/
public View create(Element elem) {
if (textArea.getLineWrap()) {
return new WrappedPlainView(elem, textArea.getWrapStyleWord());
}
else {
return new PlainView(elem);
}
}
/*****************************************************************************/
/**
* Create a default action map. This action map contains actions for all
* basic text area work - cut, copy, paste, select, caret motion, etc.
*/
ActionMap createActionMap() {
// Get the actions of the text area (which in turn gets them from its
// DefaultEditorKit).
ActionMap map = new ActionMapUIResource();
Action[] actions = textArea.getActions();
int n = actions.length;
for (int i = 0; i < n; i++) {
Action a = actions[i];
map.put(a.getValue(Action.NAME), a);
}
// Make some basic actions shared only between instances of RTextArea
// (as opposed to all JTextComponents) so we can do with them what we
// like.
// FIXME: Make sure I'm right!
map.put(DefaultEditorKit.cutAction,
RTextArea.getAction(RTextArea.CUT_ACTION));
map.put(DefaultEditorKit.copyAction,
RTextArea.getAction(RTextArea.COPY_ACTION));
map.put(DefaultEditorKit.pasteAction,
RTextArea.getAction(RTextArea.PASTE_ACTION));
map.put(DefaultEditorKit.deleteNextCharAction,
RTextArea.getAction(RTextArea.DELETE_ACTION));
map.put(DefaultEditorKit.selectAllAction,
RTextArea.getAction(RTextArea.SELECT_ALL_ACTION));
// Not sure if we need these; not sure they are ever called
// (check their NAMEs).
map.put(TransferHandler.getCutAction().getValue(Action.NAME),
TransferHandler.getCutAction());
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
return map;
}
/*****************************************************************************/
/**
* Returns the default caret for an <code>RTextArea</code>. This caret is
* capable of displaying itself differently for insert/overwrite modes.
*/
protected Caret createCaret() {
Caret caret = new ConfigurableCaret();
caret.setBlinkRate(500);
return caret;
}
/*****************************************************************************/
/**
* Creates the default highlighter for this text area.
*/
protected Highlighter createHighlighter() {
return new DefaultHighlighter();
}
/*****************************************************************************/
/**
* Creates the keymap for this text area. This simply returns the default
* <code>JTextComponent</code> keymap, which I believe is empty, as Sun
* likes the <code>InputMap</code>/<code>ActionMap</code> approach to input
* better.
*/
protected Keymap createKeymap() {
// Load the keymap we'll be using (it's saved by
// JTextComponent.addKeymap).
// NOTE that this is EMPTY because the preferred route is to use
// the InputMap/ActionMap route now (right?).
Keymap map = JTextComponent.getKeymap(RTEXTAREA_KEYMAP_NAME);
if (map == null) {
Keymap parent = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
map = JTextComponent.addKeymap(RTEXTAREA_KEYMAP_NAME, parent);
map.setDefaultAction(new RTextAreaEditorKit.DefaultKeyTypedAction());
}
return map;
}
/*****************************************************************************/
/**
* Causes the portion of the view responsible for the
* given part of the model to be repainted. Does nothing if
* the view is not currently painted.
*
* @param tc the text component for which this UI is installed
* @param p0 the beginning of the range >= 0
* @param p1 the end of the range >= p0
* @see TextUI#damageRange
*/
public void damageRange(JTextComponent tc, int p0, int p1) {
damageRange(tc, p0, p1, Position.Bias.Forward, Position.Bias.Backward);
}
/*****************************************************************************/
/**
* Causes the portion of the view responsible for the
* given part of the model to be repainted.
*
* @param p0 the beginning of the range >= 0
* @param p1 the end of the range >= p0
*/
public void damageRange(JTextComponent t, int p0, int p1,
Position.Bias p0Bias, Position.Bias p1Bias) {
if (painted) {
Rectangle alloc = getVisibleEditorRect();
RTextAreaDocument doc = (RTextAreaDocument) t.getDocument();
doc.readLock();
try {
rootView.setSize(alloc.width, alloc.height);
Shape toDamage = rootView.modelToView(p0, p0Bias,
p1, p1Bias, alloc);
Rectangle rect = (toDamage instanceof Rectangle) ?
(Rectangle) toDamage : toDamage.getBounds();
textArea.repaint(rect.x, rect.y, rect.width, rect.height);
}
catch (BadLocationException e) {
}
finally {
doc.readUnlock();
}
}
}
/*****************************************************************************/
/**
* Fetch an action map to use.
*/
ActionMap getActionMap() {
// Get the UIManager-cached action map; if this is the first
// RTextArea created, create the action map and cache it.
ActionMap map = (ActionMap) UIManager.get(getActionMapName());
if (map == null) {
map = createActionMap();
UIManager.put(SHARED_ACTION_MAP_NAME, map);
}
ActionMap componentMap = new ActionMapUIResource();
componentMap.put("requestFocus", new FocusAction());
if (map != null) {
componentMap.setParent(map);
}
return componentMap;
}
/*****************************************************************************/
/**
* Returns the name to use to cache/fetch the shared action map. This
* should be overridden by subclasses if the subclass has its own custom
* editor kit to install, so its actions get picked up.
*
* @return The name of the cached action map.
*/
protected String getActionMapName() {
return SHARED_ACTION_MAP_NAME;
}
/*****************************************************************************/
/**
* Fetches the EditorKit for the UI.
*
* @param tc the text component for which this UI is installed
* @return the editor capabilities
* @see TextUI#getEditorKit
*/
public EditorKit getEditorKit(JTextComponent tc) {
return defaultKit;
}
/*****************************************************************************/
/**
* Get the InputMap to use for the UI.
*/
protected InputMap getInputMap() {
InputMap map = new InputMapUIResource();
InputMap shared = (InputMap) UIManager.get(SHARED_INPUT_MAP_NAME);
if (shared == null) {
shared = new RTADefaultInputMap();
UIManager.put(SHARED_INPUT_MAP_NAME, shared);
}
//KeyStroke[] keys = shared.allKeys();
//for (int i=0; i<keys.length; i++)
// System.err.println(keys[i] + " -> " + shared.get(keys[i]));
if (shared != null) {
map.setParent(shared);
}
return map;
}
/*****************************************************************************/
/**
* Gets the minimum size for the editor component.
*
* @param c the editor component
* @return the size
*/
public Dimension getMinimumSize(JComponent c) {
RTextAreaDocument doc = (RTextAreaDocument) textArea.getDocument();
Insets i = c.getInsets();
Dimension d = new Dimension();
doc.readLock();
try {
d.width = (int) rootView.getMinimumSpan(View.X_AXIS) + i.left + i.right;
d.height = (int) rootView.getMinimumSpan(View.Y_AXIS) + i.top + i.bottom;
}
finally {
doc.readUnlock();
}
return d;
}
/*****************************************************************************/
/**
* Gets the maximum size for the editor component.
*
* @param c the editor component
* @return the size
*/
public Dimension getMaximumSize(JComponent c) {
RTextAreaDocument doc = (RTextAreaDocument) textArea.getDocument();
Insets i = c.getInsets();
Dimension d = new Dimension();
doc.readLock();
try {
d.width = (int) Math.min( (long) rootView.getMaximumSpan(View.X_AXIS) +
(long) i.left + (long) i.right,
Integer.MAX_VALUE);
d.height = (int) Math.min( (long) rootView.getMaximumSpan(View.Y_AXIS) +
(long) i.top + (long) i.bottom,
Integer.MAX_VALUE);
}
finally {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -