svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.utils / src / main / java / org / gvsig / utils / console / jedit / TextAreaPainter.java @ 40561
History | View | Annotate | Download (17.8 KB)
1 |
/**
|
---|---|
2 |
* gvSIG. Desktop Geographic Information System.
|
3 |
*
|
4 |
* Copyright (C) 2007-2013 gvSIG Association.
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* as published by the Free Software Foundation; either version 3
|
9 |
* of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This program is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with this program; if not, write to the Free Software
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 |
* MA 02110-1301, USA.
|
20 |
*
|
21 |
* For any additional information, do not hesitate to contact us
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
23 |
*/
|
24 |
package org.gvsig.utils.console.jedit; |
25 |
/*
|
26 |
* TextAreaPainter.java - Paints the text area
|
27 |
* Copyright (C) 1999 Slava Pestov
|
28 |
*
|
29 |
* You may use and modify this package for any purpose. Redistribution is
|
30 |
* permitted, in both source and binary form, provided that this notice
|
31 |
* remains intact in all source distributions of this package.
|
32 |
*/
|
33 |
|
34 |
import java.awt.Color; |
35 |
import java.awt.Cursor; |
36 |
import java.awt.Dimension; |
37 |
import java.awt.Font; |
38 |
import java.awt.FontMetrics; |
39 |
import java.awt.Graphics; |
40 |
import java.awt.Rectangle; |
41 |
import java.awt.Toolkit; |
42 |
import java.awt.event.MouseEvent; |
43 |
|
44 |
import javax.swing.JComponent; |
45 |
import javax.swing.ToolTipManager; |
46 |
import javax.swing.text.PlainDocument; |
47 |
import javax.swing.text.Segment; |
48 |
import javax.swing.text.TabExpander; |
49 |
import javax.swing.text.Utilities; |
50 |
|
51 |
/**
|
52 |
* The text area repaint manager. It performs double buffering and paints
|
53 |
* lines of text.
|
54 |
* @author Slava Pestov
|
55 |
* @version $Id$
|
56 |
*/
|
57 |
public class TextAreaPainter extends JComponent implements TabExpander |
58 |
{ |
59 |
/**
|
60 |
* Creates a new repaint manager. This should be not be called
|
61 |
* directly.
|
62 |
*/
|
63 |
public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults)
|
64 |
{ |
65 |
this.textArea = textArea;
|
66 |
|
67 |
setAutoscrolls(true);
|
68 |
setDoubleBuffered(true);
|
69 |
setOpaque(true);
|
70 |
|
71 |
ToolTipManager.sharedInstance().registerComponent(this); |
72 |
|
73 |
currentLine = new Segment(); |
74 |
currentLineIndex = -1;
|
75 |
|
76 |
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); |
77 |
|
78 |
setFont(new Font("Monospaced",Font.PLAIN,14)); |
79 |
setForeground(Color.black);
|
80 |
setBackground(Color.white);
|
81 |
|
82 |
blockCaret = defaults.blockCaret; |
83 |
styles = defaults.styles; |
84 |
cols = defaults.cols; |
85 |
rows = defaults.rows; |
86 |
caretColor = defaults.caretColor; |
87 |
selectionColor = defaults.selectionColor; |
88 |
lineHighlightColor = defaults.lineHighlightColor; |
89 |
lineHighlight = defaults.lineHighlight; |
90 |
bracketHighlightColor = defaults.bracketHighlightColor; |
91 |
bracketHighlight = defaults.bracketHighlight; |
92 |
paintInvalid = defaults.paintInvalid; |
93 |
eolMarkerColor = defaults.eolMarkerColor; |
94 |
eolMarkers = defaults.eolMarkers; |
95 |
} |
96 |
|
97 |
/**
|
98 |
* Returns if this component can be traversed by pressing the
|
99 |
* Tab key. This returns false.
|
100 |
*/
|
101 |
public final boolean isManagingFocus() |
102 |
{ |
103 |
return false; |
104 |
} |
105 |
|
106 |
/**
|
107 |
* Returns the syntax styles used to paint colorized text. Entry <i>n</i>
|
108 |
* will be used to paint tokens with id = <i>n</i>.
|
109 |
* @see org.gjt.sp.jedit.syntax.Token
|
110 |
*/
|
111 |
public final SyntaxStyle[] getStyles() |
112 |
{ |
113 |
return styles;
|
114 |
} |
115 |
|
116 |
/**
|
117 |
* Sets the syntax styles used to paint colorized text. Entry <i>n</i>
|
118 |
* will be used to paint tokens with id = <i>n</i>.
|
119 |
* @param styles The syntax styles
|
120 |
* @see org.gjt.sp.jedit.syntax.Token
|
121 |
*/
|
122 |
public final void setStyles(SyntaxStyle[] styles) |
123 |
{ |
124 |
this.styles = styles;
|
125 |
repaint(); |
126 |
} |
127 |
|
128 |
/**
|
129 |
* Returns the caret color.
|
130 |
*/
|
131 |
public final Color getCaretColor() |
132 |
{ |
133 |
return caretColor;
|
134 |
} |
135 |
|
136 |
/**
|
137 |
* Sets the caret color.
|
138 |
* @param caretColor The caret color
|
139 |
*/
|
140 |
public final void setCaretColor(Color caretColor) |
141 |
{ |
142 |
this.caretColor = caretColor;
|
143 |
invalidateSelectedLines(); |
144 |
} |
145 |
|
146 |
/**
|
147 |
* Returns the selection color.
|
148 |
*/
|
149 |
public final Color getSelectionColor() |
150 |
{ |
151 |
return selectionColor;
|
152 |
} |
153 |
|
154 |
/**
|
155 |
* Sets the selection color.
|
156 |
* @param selectionColor The selection color
|
157 |
*/
|
158 |
public final void setSelectionColor(Color selectionColor) |
159 |
{ |
160 |
this.selectionColor = selectionColor;
|
161 |
invalidateSelectedLines(); |
162 |
} |
163 |
|
164 |
/**
|
165 |
* Returns the line highlight color.
|
166 |
*/
|
167 |
public final Color getLineHighlightColor() |
168 |
{ |
169 |
return lineHighlightColor;
|
170 |
} |
171 |
|
172 |
/**
|
173 |
* Sets the line highlight color.
|
174 |
* @param lineHighlightColor The line highlight color
|
175 |
*/
|
176 |
public final void setLineHighlightColor(Color lineHighlightColor) |
177 |
{ |
178 |
this.lineHighlightColor = lineHighlightColor;
|
179 |
invalidateSelectedLines(); |
180 |
} |
181 |
|
182 |
/**
|
183 |
* Returns true if line highlight is enabled, false otherwise.
|
184 |
*/
|
185 |
public final boolean isLineHighlightEnabled() |
186 |
{ |
187 |
return lineHighlight;
|
188 |
} |
189 |
|
190 |
/**
|
191 |
* Enables or disables current line highlighting.
|
192 |
* @param lineHighlight True if current line highlight should be enabled,
|
193 |
* false otherwise
|
194 |
*/
|
195 |
public final void setLineHighlightEnabled(boolean lineHighlight) |
196 |
{ |
197 |
this.lineHighlight = lineHighlight;
|
198 |
invalidateSelectedLines(); |
199 |
} |
200 |
|
201 |
/**
|
202 |
* Returns the bracket highlight color.
|
203 |
*/
|
204 |
public final Color getBracketHighlightColor() |
205 |
{ |
206 |
return bracketHighlightColor;
|
207 |
} |
208 |
|
209 |
/**
|
210 |
* Sets the bracket highlight color.
|
211 |
* @param bracketHighlightColor The bracket highlight color
|
212 |
*/
|
213 |
public final void setBracketHighlightColor(Color bracketHighlightColor) |
214 |
{ |
215 |
this.bracketHighlightColor = bracketHighlightColor;
|
216 |
invalidateLine(textArea.getBracketLine()); |
217 |
} |
218 |
|
219 |
/**
|
220 |
* Returns true if bracket highlighting is enabled, false otherwise.
|
221 |
* When bracket highlighting is enabled, the bracket matching the
|
222 |
* one before the caret (if any) is highlighted.
|
223 |
*/
|
224 |
public final boolean isBracketHighlightEnabled() |
225 |
{ |
226 |
return bracketHighlight;
|
227 |
} |
228 |
|
229 |
/**
|
230 |
* Enables or disables bracket highlighting.
|
231 |
* When bracket highlighting is enabled, the bracket matching the
|
232 |
* one before the caret (if any) is highlighted.
|
233 |
* @param bracketHighlight True if bracket highlighting should be
|
234 |
* enabled, false otherwise
|
235 |
*/
|
236 |
public final void setBracketHighlightEnabled(boolean bracketHighlight) |
237 |
{ |
238 |
this.bracketHighlight = bracketHighlight;
|
239 |
invalidateLine(textArea.getBracketLine()); |
240 |
} |
241 |
|
242 |
/**
|
243 |
* Returns true if the caret should be drawn as a block, false otherwise.
|
244 |
*/
|
245 |
public final boolean isBlockCaretEnabled() |
246 |
{ |
247 |
return blockCaret;
|
248 |
} |
249 |
|
250 |
/**
|
251 |
* Sets if the caret should be drawn as a block, false otherwise.
|
252 |
* @param blockCaret True if the caret should be drawn as a block,
|
253 |
* false otherwise.
|
254 |
*/
|
255 |
public final void setBlockCaretEnabled(boolean blockCaret) |
256 |
{ |
257 |
this.blockCaret = blockCaret;
|
258 |
invalidateSelectedLines(); |
259 |
} |
260 |
|
261 |
/**
|
262 |
* Returns the EOL marker color.
|
263 |
*/
|
264 |
public final Color getEOLMarkerColor() |
265 |
{ |
266 |
return eolMarkerColor;
|
267 |
} |
268 |
|
269 |
/**
|
270 |
* Sets the EOL marker color.
|
271 |
* @param eolMarkerColor The EOL marker color
|
272 |
*/
|
273 |
public final void setEOLMarkerColor(Color eolMarkerColor) |
274 |
{ |
275 |
this.eolMarkerColor = eolMarkerColor;
|
276 |
repaint(); |
277 |
} |
278 |
|
279 |
/**
|
280 |
* Returns true if EOL markers are drawn, false otherwise.
|
281 |
*/
|
282 |
public final boolean getEOLMarkersPainted() |
283 |
{ |
284 |
return eolMarkers;
|
285 |
} |
286 |
|
287 |
/**
|
288 |
* Sets if EOL markers are to be drawn.
|
289 |
* @param eolMarkers True if EOL markers should be drawn, false otherwise
|
290 |
*/
|
291 |
public final void setEOLMarkersPainted(boolean eolMarkers) |
292 |
{ |
293 |
this.eolMarkers = eolMarkers;
|
294 |
repaint(); |
295 |
} |
296 |
|
297 |
/**
|
298 |
* Returns true if invalid lines are painted as red tildes (~),
|
299 |
* false otherwise.
|
300 |
*/
|
301 |
public boolean getInvalidLinesPainted() |
302 |
{ |
303 |
return paintInvalid;
|
304 |
} |
305 |
|
306 |
/**
|
307 |
* Sets if invalid lines are to be painted as red tildes.
|
308 |
* @param paintInvalid True if invalid lines should be drawn, false otherwise
|
309 |
*/
|
310 |
public void setInvalidLinesPainted(boolean paintInvalid) |
311 |
{ |
312 |
this.paintInvalid = paintInvalid;
|
313 |
} |
314 |
|
315 |
/**
|
316 |
* Adds a custom highlight painter.
|
317 |
* @param highlight The highlight
|
318 |
*/
|
319 |
public void addCustomHighlight(Highlight highlight) |
320 |
{ |
321 |
highlight.init(textArea,highlights); |
322 |
highlights = highlight; |
323 |
} |
324 |
|
325 |
/**
|
326 |
* Highlight interface.
|
327 |
*/
|
328 |
public interface Highlight |
329 |
{ |
330 |
/**
|
331 |
* Called after the highlight painter has been added.
|
332 |
* @param textArea The text area
|
333 |
* @param next The painter this one should delegate to
|
334 |
*/
|
335 |
void init(JEditTextArea textArea, Highlight next);
|
336 |
|
337 |
/**
|
338 |
* This should paint the highlight and delgate to the
|
339 |
* next highlight painter.
|
340 |
* @param gfx The graphics context
|
341 |
* @param line The line number
|
342 |
* @param y The y co-ordinate of the line
|
343 |
*/
|
344 |
void paintHighlight(Graphics gfx, int line, int y); |
345 |
|
346 |
/**
|
347 |
* Returns the tool tip to display at the specified
|
348 |
* location. If this highlighter doesn't know what to
|
349 |
* display, it should delegate to the next highlight
|
350 |
* painter.
|
351 |
* @param evt The mouse event
|
352 |
*/
|
353 |
String getToolTipText(MouseEvent evt); |
354 |
} |
355 |
|
356 |
/**
|
357 |
* Returns the tool tip to display at the specified location.
|
358 |
* @param evt The mouse event
|
359 |
*/
|
360 |
public String getToolTipText(MouseEvent evt) |
361 |
{ |
362 |
if(highlights != null) |
363 |
return highlights.getToolTipText(evt);
|
364 |
else
|
365 |
return null; |
366 |
} |
367 |
|
368 |
/**
|
369 |
* Returns the font metrics used by this component.
|
370 |
*/
|
371 |
public FontMetrics getFontMetrics() |
372 |
{ |
373 |
return fm;
|
374 |
} |
375 |
|
376 |
/**
|
377 |
* Sets the font for this component. This is overridden to update the
|
378 |
* cached font metrics and to recalculate which lines are visible.
|
379 |
* @param font The font
|
380 |
*/
|
381 |
public void setFont(Font font) |
382 |
{ |
383 |
super.setFont(font);
|
384 |
fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
|
385 |
textArea.recalculateVisibleLines(); |
386 |
} |
387 |
|
388 |
/**
|
389 |
* Repaints the text.
|
390 |
* @param g The graphics context
|
391 |
*/
|
392 |
public void paint(Graphics gfx) |
393 |
{ |
394 |
tabSize = fm.charWidth(' ') * ((Integer)textArea |
395 |
.getDocument().getProperty( |
396 |
PlainDocument.tabSizeAttribute)).intValue();
|
397 |
|
398 |
Rectangle clipRect = gfx.getClipBounds();
|
399 |
|
400 |
gfx.setColor(getBackground()); |
401 |
gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height); |
402 |
|
403 |
// We don't use yToLine() here because that method doesn't
|
404 |
// return lines past the end of the document
|
405 |
int height = fm.getHeight();
|
406 |
int firstLine = textArea.getFirstLine();
|
407 |
int firstInvalid = firstLine + clipRect.y / height;
|
408 |
// Because the clipRect's height is usually an even multiple
|
409 |
// of the font height, we subtract 1 from it, otherwise one
|
410 |
// too many lines will always be painted.
|
411 |
int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; |
412 |
|
413 |
try
|
414 |
{ |
415 |
TokenMarker tokenMarker = ((SyntaxDocument)textArea.getDocument()) |
416 |
.getTokenMarker(); |
417 |
int x = textArea.getHorizontalOffset();
|
418 |
|
419 |
for(int line = firstInvalid; line <= lastInvalid; line++) |
420 |
{ |
421 |
paintLine(gfx,tokenMarker,line,x); |
422 |
} |
423 |
|
424 |
if(tokenMarker != null && tokenMarker.isNextLineRequested()) |
425 |
{ |
426 |
int h = clipRect.y + clipRect.height;
|
427 |
repaint(0,h,getWidth(),getHeight() - h);
|
428 |
} |
429 |
} |
430 |
catch(Exception e) |
431 |
{ |
432 |
System.err.println("Error repainting line" |
433 |
+ " range {" + firstInvalid + "," |
434 |
+ lastInvalid + "}:");
|
435 |
e.printStackTrace(); |
436 |
} |
437 |
} |
438 |
|
439 |
/**
|
440 |
* Marks a line as needing a repaint.
|
441 |
* @param line The line to invalidate
|
442 |
*/
|
443 |
public final void invalidateLine(int line) |
444 |
{ |
445 |
repaint(0,textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(),
|
446 |
getWidth(),fm.getHeight()); |
447 |
} |
448 |
|
449 |
/**
|
450 |
* Marks a range of lines as needing a repaint.
|
451 |
* @param firstLine The first line to invalidate
|
452 |
* @param lastLine The last line to invalidate
|
453 |
*/
|
454 |
public final void invalidateLineRange(int firstLine, int lastLine) |
455 |
{ |
456 |
repaint(0,textArea.lineToY(firstLine) + fm.getMaxDescent() + fm.getLeading(),
|
457 |
getWidth(),(lastLine - firstLine + 1) * fm.getHeight());
|
458 |
} |
459 |
|
460 |
/**
|
461 |
* Repaints the lines containing the selection.
|
462 |
*/
|
463 |
public final void invalidateSelectedLines() |
464 |
{ |
465 |
invalidateLineRange(textArea.getSelectionStartLine(), |
466 |
textArea.getSelectionEndLine()); |
467 |
} |
468 |
|
469 |
/**
|
470 |
* Implementation of TabExpander interface. Returns next tab stop after
|
471 |
* a specified point.
|
472 |
* @param x The x co-ordinate
|
473 |
* @param tabOffset Ignored
|
474 |
* @return The next tab stop after <i>x</i>
|
475 |
*/
|
476 |
public float nextTabStop(float x, int tabOffset) |
477 |
{ |
478 |
int offset = textArea.getHorizontalOffset();
|
479 |
int ntabs = ((int)x - offset) / tabSize; |
480 |
return (ntabs + 1) * tabSize + offset; |
481 |
} |
482 |
|
483 |
/**
|
484 |
* Returns the painter's preferred size.
|
485 |
*/
|
486 |
public Dimension getPreferredSize() |
487 |
{ |
488 |
Dimension dim = new Dimension(); |
489 |
dim.width = fm.charWidth('w') * cols;
|
490 |
dim.height = fm.getHeight() * rows; |
491 |
return dim;
|
492 |
} |
493 |
|
494 |
|
495 |
/**
|
496 |
* Returns the painter's minimum size.
|
497 |
*/
|
498 |
public Dimension getMinimumSize() |
499 |
{ |
500 |
return getPreferredSize();
|
501 |
} |
502 |
|
503 |
// package-private members
|
504 |
int currentLineIndex;
|
505 |
Token currentLineTokens; |
506 |
Segment currentLine;
|
507 |
|
508 |
// protected members
|
509 |
protected JEditTextArea textArea;
|
510 |
|
511 |
protected SyntaxStyle[] styles; |
512 |
protected Color caretColor; |
513 |
protected Color selectionColor; |
514 |
protected Color lineHighlightColor; |
515 |
protected Color bracketHighlightColor; |
516 |
protected Color eolMarkerColor; |
517 |
|
518 |
protected boolean blockCaret; |
519 |
protected boolean lineHighlight; |
520 |
protected boolean bracketHighlight; |
521 |
protected boolean paintInvalid; |
522 |
protected boolean eolMarkers; |
523 |
protected int cols; |
524 |
protected int rows; |
525 |
|
526 |
protected int tabSize; |
527 |
protected FontMetrics fm; |
528 |
|
529 |
protected Highlight highlights;
|
530 |
|
531 |
protected void paintLine(Graphics gfx, TokenMarker tokenMarker, |
532 |
int line, int x) |
533 |
{ |
534 |
Font defaultFont = getFont();
|
535 |
Color defaultColor = getForeground();
|
536 |
|
537 |
currentLineIndex = line; |
538 |
int y = textArea.lineToY(line);
|
539 |
|
540 |
if(line < 0 || line >= textArea.getLineCount()) |
541 |
{ |
542 |
if(paintInvalid)
|
543 |
{ |
544 |
paintHighlight(gfx,line,y); |
545 |
styles[Token.INVALID].setGraphicsFlags(gfx,defaultFont); |
546 |
gfx.drawString("~",0,y + fm.getHeight()); |
547 |
} |
548 |
} |
549 |
else if(tokenMarker == null) |
550 |
{ |
551 |
paintPlainLine(gfx,line,defaultFont,defaultColor,x,y); |
552 |
} |
553 |
else
|
554 |
{ |
555 |
paintSyntaxLine(gfx,tokenMarker,line,defaultFont, |
556 |
defaultColor,x,y); |
557 |
} |
558 |
} |
559 |
|
560 |
protected void paintPlainLine(Graphics gfx, int line, Font defaultFont, |
561 |
Color defaultColor, int x, int y) |
562 |
{ |
563 |
paintHighlight(gfx,line,y); |
564 |
textArea.getLineText(line,currentLine); |
565 |
|
566 |
gfx.setFont(defaultFont); |
567 |
gfx.setColor(defaultColor); |
568 |
|
569 |
y += fm.getHeight(); |
570 |
x = Utilities.drawTabbedText(currentLine,x,y,gfx,this,0); |
571 |
|
572 |
if(eolMarkers)
|
573 |
{ |
574 |
gfx.setColor(eolMarkerColor); |
575 |
gfx.drawString(".",x,y);
|
576 |
} |
577 |
} |
578 |
|
579 |
protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker, |
580 |
int line, Font defaultFont, Color defaultColor, int x, int y) |
581 |
{ |
582 |
textArea.getLineText(currentLineIndex,currentLine); |
583 |
currentLineTokens = tokenMarker.markTokens(currentLine, |
584 |
currentLineIndex); |
585 |
|
586 |
paintHighlight(gfx,line,y); |
587 |
|
588 |
gfx.setFont(defaultFont); |
589 |
gfx.setColor(defaultColor); |
590 |
y += fm.getHeight(); |
591 |
x = SyntaxUtilities.paintSyntaxLine(currentLine, |
592 |
currentLineTokens,styles,this,gfx,x,y);
|
593 |
|
594 |
if(eolMarkers)
|
595 |
{ |
596 |
gfx.setColor(eolMarkerColor); |
597 |
gfx.drawString(".",x,y);
|
598 |
} |
599 |
} |
600 |
|
601 |
protected void paintHighlight(Graphics gfx, int line, int y) |
602 |
{ |
603 |
if(line >= textArea.getSelectionStartLine()
|
604 |
&& line <= textArea.getSelectionEndLine()) |
605 |
paintLineHighlight(gfx,line,y); |
606 |
|
607 |
if(highlights != null) |
608 |
highlights.paintHighlight(gfx,line,y); |
609 |
|
610 |
if(bracketHighlight && line == textArea.getBracketLine())
|
611 |
paintBracketHighlight(gfx,line,y); |
612 |
|
613 |
if(line == textArea.getCaretLine())
|
614 |
paintCaret(gfx,line,y); |
615 |
} |
616 |
|
617 |
protected void paintLineHighlight(Graphics gfx, int line, int y) |
618 |
{ |
619 |
int height = fm.getHeight();
|
620 |
y += fm.getLeading() + fm.getMaxDescent(); |
621 |
|
622 |
int selectionStart = textArea.getSelectionStart();
|
623 |
int selectionEnd = textArea.getSelectionEnd();
|
624 |
|
625 |
if(selectionStart == selectionEnd)
|
626 |
{ |
627 |
if(lineHighlight)
|
628 |
{ |
629 |
gfx.setColor(lineHighlightColor); |
630 |
gfx.fillRect(0,y,getWidth(),height);
|
631 |
} |
632 |
} |
633 |
else
|
634 |
{ |
635 |
gfx.setColor(selectionColor); |
636 |
|
637 |
int selectionStartLine = textArea.getSelectionStartLine();
|
638 |
int selectionEndLine = textArea.getSelectionEndLine();
|
639 |
int lineStart = textArea.getLineStartOffset(line);
|
640 |
|
641 |
int x1, x2;
|
642 |
if(textArea.isSelectionRectangular())
|
643 |
{ |
644 |
int lineLen = textArea.getLineLength(line);
|
645 |
x1 = textArea._offsetToX(line,Math.min(lineLen,
|
646 |
selectionStart - textArea.getLineStartOffset( |
647 |
selectionStartLine))); |
648 |
x2 = textArea._offsetToX(line,Math.min(lineLen,
|
649 |
selectionEnd - textArea.getLineStartOffset( |
650 |
selectionEndLine))); |
651 |
if(x1 == x2)
|
652 |
x2++; |
653 |
} |
654 |
else if(selectionStartLine == selectionEndLine) |
655 |
{ |
656 |
x1 = textArea._offsetToX(line, |
657 |
selectionStart - lineStart); |
658 |
x2 = textArea._offsetToX(line, |
659 |
selectionEnd - lineStart); |
660 |
} |
661 |
else if(line == selectionStartLine) |
662 |
{ |
663 |
x1 = textArea._offsetToX(line, |
664 |
selectionStart - lineStart); |
665 |
x2 = getWidth(); |
666 |
} |
667 |
else if(line == selectionEndLine) |
668 |
{ |
669 |
x1 = 0;
|
670 |
x2 = textArea._offsetToX(line, |
671 |
selectionEnd - lineStart); |
672 |
} |
673 |
else
|
674 |
{ |
675 |
x1 = 0;
|
676 |
x2 = getWidth(); |
677 |
} |
678 |
|
679 |
// "inlined" min/max()
|
680 |
gfx.fillRect(x1 > x2 ? x2 : x1,y,x1 > x2 ? |
681 |
(x1 - x2) : (x2 - x1),height); |
682 |
} |
683 |
|
684 |
} |
685 |
|
686 |
protected void paintBracketHighlight(Graphics gfx, int line, int y) |
687 |
{ |
688 |
int position = textArea.getBracketPosition();
|
689 |
if(position == -1) |
690 |
return;
|
691 |
y += fm.getLeading() + fm.getMaxDescent(); |
692 |
int x = textArea._offsetToX(line,position);
|
693 |
gfx.setColor(bracketHighlightColor); |
694 |
// Hack!!! Since there is no fast way to get the character
|
695 |
// from the bracket matching routine, we use ( since all
|
696 |
// brackets probably have the same width anyway
|
697 |
gfx.drawRect(x,y,fm.charWidth('(') - 1, |
698 |
fm.getHeight() - 1);
|
699 |
} |
700 |
|
701 |
protected void paintCaret(Graphics gfx, int line, int y) |
702 |
{ |
703 |
if(textArea.isCaretVisible())
|
704 |
{ |
705 |
int offset = textArea.getCaretPosition()
|
706 |
- textArea.getLineStartOffset(line); |
707 |
int caretX = textArea._offsetToX(line,offset);
|
708 |
int caretWidth = ((blockCaret ||
|
709 |
textArea.isOverwriteEnabled()) ? |
710 |
fm.charWidth('w') : 1); |
711 |
y += fm.getLeading() + fm.getMaxDescent(); |
712 |
int height = fm.getHeight();
|
713 |
|
714 |
gfx.setColor(caretColor); |
715 |
|
716 |
if(textArea.isOverwriteEnabled())
|
717 |
{ |
718 |
gfx.fillRect(caretX,y + height - 1,
|
719 |
caretWidth,1);
|
720 |
} |
721 |
else
|
722 |
{ |
723 |
gfx.drawRect(caretX,y,caretWidth - 1,height - 1); |
724 |
} |
725 |
} |
726 |
} |
727 |
} |