/*
* 02/24/2004
* RSyntaxTextAreaUI.java - UI for an RSyntaxTextArea.
* This library is distributed under a modified BSD license. See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.rsyntaxtextarea;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.text.BadLocationException;
import javax.swing.text.EditorKit;
import javax.swing.text.Element;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaUI;
/**
* UI used by RSyntaxTextArea. This allows us to implement syntax
* highlighting.
*
* @author Robert Futrell
* @version 0.1
*/
public class RSyntaxTextAreaUI extends RTextAreaUI {
private static final String SHARED_ACTION_MAP_NAME = "RSyntaxTextAreaUI.actionMap";
private static final String SHARED_INPUT_MAP_NAME = "RSyntaxTextAreaUI.inputMap";
private static final EditorKit DEFAULT_KIT = new RSyntaxTextAreaEditorKit();
public static ComponentUI createUI(JComponent ta) {
return new RSyntaxTextAreaUI(ta);
}
/**
* Constructor.
*/
public RSyntaxTextAreaUI(JComponent rSyntaxTextArea) {
super(rSyntaxTextArea);
}
/**
* Creates the view for an element.
*
* @param elem The element.
* @return The view.
*/
@Override
public View create(Element elem) {
RTextArea c = getRTextArea();
if (c instanceof RSyntaxTextArea) {
RSyntaxTextArea area = (RSyntaxTextArea) c;
View v;
if (area.getLineWrap()) {
v = new WrappedSyntaxView(elem);
} else {
v = new SyntaxView(elem);
}
return v;
}
return null;
}
/**
* Creates the highlighter to use for syntax text areas.
*
* @return The highlighter.
*/
@Override
protected Highlighter createHighlighter() {
return new RSyntaxTextAreaHighlighter();
}
/**
* 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.
*/
@Override
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 javax.swing.plaf.TextUI#getEditorKit
*/
@Override
public EditorKit getEditorKit(JTextComponent tc) {
return DEFAULT_KIT;
}
/**
* Get the InputMap to use for the UI.
*
*
* This method is not named
*
* This method is quicker than using traditional
*
* This is faster than calling getInputMap() because there is a
* package-private method in BasicTextAreaUI with that name. Thus,
* creating a new method with that name causes certain compilers to issue
* warnings that you are not actually overriding the original method (since it
* is package-private).
*/
@Override
protected InputMap getRTextAreaInputMap() {
InputMap map = new InputMapUIResource();
InputMap shared = (InputMap) UIManager.get(SHARED_INPUT_MAP_NAME);
if (shared == null) {
shared = new RSyntaxTextAreaDefaultInputMap();
UIManager.put(SHARED_INPUT_MAP_NAME, shared);
}
// KeyStroke[] keys = shared.allKeys();
// for (int i=0; iRSyntaxTextArea.
*
* @param e The property change event.
*/
@Override
protected void propertyChange(PropertyChangeEvent e) {
String name = e.getPropertyName();
// If they change the syntax scheme, we must do this so that
// WrappedSyntaxView(_TEST) updates its child views properly.
if (name.equals(RSyntaxTextArea.SYNTAX_SCHEME_PROPERTY)) {
modelChanged();
}
// Everything else is general to all RTextAreas.
else {
super.propertyChange(e);
}
}
/**
* Updates the view. This should be called when the underlying
* RSyntaxTextArea changes its syntax editing style.
*/
public void refreshSyntaxHighlighting() {
modelChanged();
}
/**
* Returns the y-coordinate of the specified line.
* modelToView(int)
* calls, as the entire bounding box isn't computed.
*/
@Override
public int yForLine(int line) throws BadLocationException {
Rectangle alloc = getVisibleEditorRect();
if (alloc != null) {
RSTAView view = (RSTAView) getRootView(textArea).getView(0);
return view.yForLine(alloc, line);
}
return -1;
}
/**
* Returns the y-coordinate of the line containing a specified offset.
* modelToView(offs).y, so it is
* preferred if you do not need the actual bounding box.
*/
@Override
public int yForLineContaining(int offs) throws BadLocationException {
Rectangle alloc = getVisibleEditorRect();
if (alloc != null) {
RSTAView view = (RSTAView) getRootView(textArea).getView(0);
return view.yForLineContaining(alloc, offs);
}
return -1;
}
}