source: other-projects/rsyntax-textarea/src/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaUI.java@ 25584

Last change on this file since 25584 was 25584, checked in by davidb, 12 years ago

Initial cut an a text edit area for GLI that supports color syntax highlighting

File size: 6.5 KB
Line 
1/*
2 * 02/24/2004
3 *
4 * RSyntaxTextAreaUI.java - UI for an RSyntaxTextArea.
5 *
6 * This library is distributed under a modified BSD license. See the included
7 * RSyntaxTextArea.License.txt file for details.
8 */
9package org.fife.ui.rsyntaxtextarea;
10
11import java.awt.Color;
12import java.awt.Graphics;
13import java.awt.Rectangle;
14import java.beans.PropertyChangeEvent;
15import javax.swing.InputMap;
16import javax.swing.JComponent;
17import javax.swing.UIManager;
18import javax.swing.plaf.ComponentUI;
19import javax.swing.plaf.InputMapUIResource;
20import javax.swing.text.*;
21
22import org.fife.ui.rtextarea.RTextArea;
23import org.fife.ui.rtextarea.RTextAreaUI;
24
25
26/**
27 * UI used by <code>RSyntaxTextArea</code>. This allows us to implement
28 * syntax highlighting.
29 *
30 * @author Robert Futrell
31 * @version 0.1
32 */
33public class RSyntaxTextAreaUI extends RTextAreaUI {
34
35 private static final String SHARED_ACTION_MAP_NAME = "RSyntaxTextAreaUI.actionMap";
36 private static final String SHARED_INPUT_MAP_NAME = "RSyntaxTextAreaUI.inputMap";
37 private static final EditorKit defaultKit = new RSyntaxTextAreaEditorKit();
38
39
40 public static ComponentUI createUI(JComponent ta) {
41 return new RSyntaxTextAreaUI(ta);
42 }
43
44
45 /**
46 * Constructor.
47 */
48 public RSyntaxTextAreaUI(JComponent rSyntaxTextArea) {
49 super(rSyntaxTextArea);
50 }
51
52
53 /**
54 * Creates the view for an element.
55 *
56 * @param elem The element.
57 * @return The view.
58 */
59 public View create(Element elem) {
60 RTextArea c = getRTextArea();
61 if (c instanceof RSyntaxTextArea) {
62 RSyntaxTextArea area = (RSyntaxTextArea) c;
63 View v;
64 if (area.getLineWrap())
65 v = new WrappedSyntaxView(elem);
66 else
67 v = new SyntaxView(elem);
68 return v;
69 }
70 return null;
71 }
72
73
74 /**
75 * Creates the highlighter to use for syntax text areas.
76 *
77 * @return The highlighter.
78 */
79 protected Highlighter createHighlighter() {
80 return new RSyntaxTextAreaHighlighter();
81 }
82
83
84 /**
85 * Returns the name to use to cache/fetch the shared action map. This
86 * should be overridden by subclasses if the subclass has its own custom
87 * editor kit to install, so its actions get picked up.
88 *
89 * @return The name of the cached action map.
90 */
91 protected String getActionMapName() {
92 return SHARED_ACTION_MAP_NAME;
93 }
94
95
96 /**
97 * Fetches the EditorKit for the UI.
98 *
99 * @param tc The text component for which this UI is installed.
100 * @return The editor capabilities.
101 * @see javax.swing.plaf.TextUI#getEditorKit
102 */
103 public EditorKit getEditorKit(JTextComponent tc) {
104 return defaultKit;
105 }
106
107
108 /**
109 * Get the InputMap to use for the UI.<p>
110 *
111 * This method is not named <code>getInputMap()</code> because there is
112 * a package-private method in <code>BasicTextAreaUI</code> with that name.
113 * Thus, creating a new method with that name causes certain compilers to
114 * issue warnings that you are not actually overriding the original method
115 * (since it is package-private).
116 */
117 protected InputMap getRTextAreaInputMap() {
118 InputMap map = new InputMapUIResource();
119 InputMap shared = (InputMap)UIManager.get(SHARED_INPUT_MAP_NAME);
120 if (shared==null) {
121 shared = new RSyntaxTextAreaDefaultInputMap();
122 UIManager.put(SHARED_INPUT_MAP_NAME, shared);
123 }
124 //KeyStroke[] keys = shared.allKeys();
125 //for (int i=0; i<keys.length; i++)
126 // System.err.println(keys[i] + " -> " + shared.get(keys[i]));
127 map.setParent(shared);
128 return map;
129 }
130
131
132 /**
133 * Paints the text area's background.
134 *
135 * @param g The graphics component on which to paint.
136 */
137 protected void paintBackground(Graphics g) {
138 super.paintBackground(g);
139 paintMatchedBracket(g);
140 }
141
142
143 /**
144 * Paints the "matched bracket", if any.
145 *
146 * @param g The graphics context.
147 */
148 protected void paintMatchedBracket(Graphics g) {
149 // We must add "-1" to the height because otherwise we'll paint below
150 // the region that gets invalidated.
151 RSyntaxTextArea rsta = (RSyntaxTextArea)textArea;
152 if (rsta.isBracketMatchingEnabled()) {
153 Rectangle match = rsta.match;
154 if (match!=null) {
155 if (rsta.getAnimateBracketMatching()) {
156 Color bg = rsta.getMatchedBracketBGColor();
157 if (bg!=null) {
158 g.setColor(bg);
159 g.fillRoundRect(match.x,match.y, match.width,match.height-1, 5,5);
160 }
161 g.setColor(rsta.getMatchedBracketBorderColor());
162 g.drawRoundRect(match.x,match.y, match.width,match.height-1, 5,5);
163 }
164 else {
165 Color bg = rsta.getMatchedBracketBGColor();
166 if (bg!=null) {
167 g.setColor(bg);
168 g.fillRect(match.x,match.y, match.width,match.height-1);
169 }
170 g.setColor(rsta.getMatchedBracketBorderColor());
171 g.drawRect(match.x,match.y, match.width,match.height-1);
172 }
173 }
174 }
175 }
176
177 /**
178 * Gets called whenever a bound property is changed on this UI's
179 * <code>RSyntaxTextArea</code>.
180 *
181 * @param e The property change event.
182 */
183 protected void propertyChange(PropertyChangeEvent e) {
184
185 String name = e.getPropertyName();
186
187 // If they change the syntax scheme, we must do this so that
188 // WrappedSyntaxView(_TEST) updates its child views properly.
189 if (name.equals(RSyntaxTextArea.SYNTAX_SCHEME_PROPERTY)) {
190 modelChanged();
191 }
192
193 // Everything else is general to all RTextAreas.
194 else {
195 super.propertyChange(e);
196 }
197
198 }
199
200
201 /**
202 * Updates the view. This should be called when the underlying
203 * <code>RSyntaxTextArea</code> changes its syntax editing style.
204 */
205 public void refreshSyntaxHighlighting() {
206 modelChanged();
207 }
208
209
210 /**
211 * Returns the y-coordinate of the specified line.<p>
212 *
213 * This method is quicker than using traditional
214 * <code>modelToView(int)</code> calls, as the entire bounding box isn't
215 * computed.
216 */
217 public int yForLine(int line) throws BadLocationException {
218 Rectangle alloc = getVisibleEditorRect();
219 if (alloc!=null) {
220 RSTAView view = (RSTAView)getRootView(textArea).getView(0);
221 return view.yForLine(alloc, line);
222 }
223 return -1;
224 }
225
226
227 /**
228 * Returns the y-coordinate of the line containing a specified offset.<p>
229 *
230 * This is faster than calling <code>modelToView(offs).y</code>, so it is
231 * preferred if you do not need the actual bounding box.
232 */
233 public int yForLineContaining(int offs) throws BadLocationException {
234 Rectangle alloc = getVisibleEditorRect();
235 if (alloc!=null) {
236 RSTAView view = (RSTAView)getRootView(textArea).getView(0);
237 return view.yForLineContaining(alloc, offs);
238 }
239 return -1;
240 }
241
242
243}
Note: See TracBrowser for help on using the repository browser.