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