1 30 31 package org.syntax.jedit; 32 33 import org.syntax.jedit.tokenmarker.*; 34 import javax.swing.ToolTipManager ; 35 import javax.swing.text.*; 36 import javax.swing.JComponent ; 37 import java.awt.event.MouseEvent ; 38 import java.awt.*; 39 40 46 public class TextAreaPainter extends JComponent implements TabExpander 47 { 48 52 public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults) 53 { 54 this.textArea = textArea; 55 56 setAutoscrolls(true); 57 setDoubleBuffered(true); 58 setOpaque(true); 59 60 ToolTipManager.sharedInstance().registerComponent(this); 61 62 currentLine = new Segment(); 63 currentLineIndex = -1; 64 65 setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); 66 67 setFont(new Font("Monospaced",Font.PLAIN,14)); 68 setForeground(Color.black); 69 setBackground(Color.white); 70 71 blockCaret = defaults.blockCaret; 72 styles = defaults.styles; 73 cols = defaults.cols; 74 rows = defaults.rows; 75 caretColor = defaults.caretColor; 76 selectionColor = defaults.selectionColor; 77 lineHighlightColor = defaults.lineHighlightColor; 78 lineHighlight = defaults.lineHighlight; 79 bracketHighlightColor = defaults.bracketHighlightColor; 80 bracketHighlight = defaults.bracketHighlight; 81 paintInvalid = defaults.paintInvalid; 82 eolMarkerColor = defaults.eolMarkerColor; 83 eolMarkers = defaults.eolMarkers; 84 } 85 86 90 public final boolean isManagingFocus() 91 { 92 return false; 93 } 94 95 100 public final SyntaxStyle[] getStyles() 101 { 102 return styles; 103 } 104 105 111 public final void setStyles(SyntaxStyle[] styles) 112 { 113 this.styles = styles; 114 repaint(); 115 } 116 117 120 public final Color getCaretColor() 121 { 122 return caretColor; 123 } 124 125 129 public final void setCaretColor(Color caretColor) 130 { 131 this.caretColor = caretColor; 132 invalidateSelectedLines(); 133 } 134 135 138 public final Color getSelectionColor() 139 { 140 return selectionColor; 141 } 142 143 147 public final void setSelectionColor(Color selectionColor) 148 { 149 this.selectionColor = selectionColor; 150 invalidateSelectedLines(); 151 } 152 153 156 public final Color getLineHighlightColor() 157 { 158 return lineHighlightColor; 159 } 160 161 165 public final void setLineHighlightColor(Color lineHighlightColor) 166 { 167 this.lineHighlightColor = lineHighlightColor; 168 invalidateSelectedLines(); 169 } 170 171 174 public final boolean isLineHighlightEnabled() 175 { 176 return lineHighlight; 177 } 178 179 184 public final void setLineHighlightEnabled(boolean lineHighlight) 185 { 186 this.lineHighlight = lineHighlight; 187 invalidateSelectedLines(); 188 } 189 190 193 public final Color getBracketHighlightColor() 194 { 195 return bracketHighlightColor; 196 } 197 198 202 public final void setBracketHighlightColor(Color bracketHighlightColor) 203 { 204 this.bracketHighlightColor = bracketHighlightColor; 205 invalidateLine(textArea.getBracketLine()); 206 } 207 208 213 public final boolean isBracketHighlightEnabled() 214 { 215 return bracketHighlight; 216 } 217 218 225 public final void setBracketHighlightEnabled(boolean bracketHighlight) 226 { 227 this.bracketHighlight = bracketHighlight; 228 invalidateLine(textArea.getBracketLine()); 229 } 230 231 234 public final boolean isBlockCaretEnabled() 235 { 236 return blockCaret; 237 } 238 239 244 public final void setBlockCaretEnabled(boolean blockCaret) 245 { 246 this.blockCaret = blockCaret; 247 invalidateSelectedLines(); 248 } 249 250 253 public final Color getEOLMarkerColor() 254 { 255 return eolMarkerColor; 256 } 257 258 262 public final void setEOLMarkerColor(Color eolMarkerColor) 263 { 264 this.eolMarkerColor = eolMarkerColor; 265 repaint(); 266 } 267 268 271 public final boolean getEOLMarkersPainted() 272 { 273 return eolMarkers; 274 } 275 276 280 public final void setEOLMarkersPainted(boolean eolMarkers) 281 { 282 this.eolMarkers = eolMarkers; 283 repaint(); 284 } 285 286 290 public boolean getInvalidLinesPainted() 291 { 292 return paintInvalid; 293 } 294 295 299 public void setInvalidLinesPainted(boolean paintInvalid) 300 { 301 this.paintInvalid = paintInvalid; 302 } 303 304 308 public void addCustomHighlight(Highlight highlight) 309 { 310 highlight.init(textArea,highlights); 311 highlights = highlight; 312 } 313 314 317 public interface Highlight 318 { 319 324 void init(JEditTextArea textArea, Highlight next); 325 326 333 void paintHighlight(Graphics gfx, int line, int y); 334 335 342 String getToolTipText(MouseEvent evt); 343 } 344 345 349 public String getToolTipText(MouseEvent evt) 350 { 351 if(highlights != null) 352 return highlights.getToolTipText(evt); 353 else 354 return null; 355 } 356 357 360 public FontMetrics getFontMetrics() 361 { 362 return fm; 363 } 364 365 370 public void setFont(Font font) 371 { 372 super.setFont(font); 373 fm = Toolkit.getDefaultToolkit().getFontMetrics(font); 374 textArea.recalculateVisibleLines(); 375 } 376 377 381 public void paint(Graphics gfx) 382 { 383 tabSize = fm.charWidth(' ') * ((Integer )textArea 384 .getDocument().getProperty( 385 PlainDocument.tabSizeAttribute)).intValue(); 386 387 Rectangle clipRect = gfx.getClipBounds(); 388 389 gfx.setColor(getBackground()); 390 gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height); 391 392 int height = fm.getHeight(); 395 int firstLine = textArea.getFirstLine(); 396 int firstInvalid = firstLine + clipRect.y / height; 397 int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; 401 402 try 403 { 404 TokenMarker tokenMarker = textArea.getDocument() 405 .getTokenMarker(); 406 int x = textArea.getHorizontalOffset(); 407 408 for(int line = firstInvalid; line <= lastInvalid; line++) 409 { 410 paintLine(gfx,tokenMarker,line,x); 411 } 412 413 if(tokenMarker != null && tokenMarker.isNextLineRequested()) 414 { 415 int h = clipRect.y + clipRect.height; 416 repaint(0,h,getWidth(),getHeight() - h); 417 } 418 } 419 catch(Exception e) 420 { 421 System.err.println("Error repainting line" 422 + " range {" + firstInvalid + "," 423 + lastInvalid + "}:"); 424 e.printStackTrace(); 425 } 426 } 427 428 432 public final void invalidateLine(int line) 433 { 434 repaint(0,textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(), 435 getWidth(),fm.getHeight()); 436 } 437 438 443 public final void invalidateLineRange(int firstLine, int lastLine) 444 { 445 repaint(0,textArea.lineToY(firstLine) + fm.getMaxDescent() + fm.getLeading(), 446 getWidth(),(lastLine - firstLine + 1) * fm.getHeight()); 447 } 448 449 452 public final void invalidateSelectedLines() 453 { 454 invalidateLineRange(textArea.getSelectionStartLine(), 455 textArea.getSelectionEndLine()); 456 } 457 458 465 public float nextTabStop(float x, int tabOffset) 466 { 467 int offset = textArea.getHorizontalOffset(); 468 int ntabs=0; 469 if (tabSize > 0) 470 ntabs = ((int)x - offset) / tabSize; 471 return (ntabs + 1) * tabSize + offset; 472 } 473 474 477 public Dimension getPreferredSize() 478 { 479 Dimension dim = new Dimension(); 480 dim.width = fm.charWidth('w') * cols; 481 dim.height = fm.getHeight() * rows; 482 return dim; 483 } 484 485 486 489 public Dimension getMinimumSize() 490 { 491 return getPreferredSize(); 492 } 493 494 int currentLineIndex; 496 Token currentLineTokens; 497 Segment currentLine; 498 499 protected JEditTextArea textArea; 501 502 protected SyntaxStyle[] styles; 503 protected Color caretColor; 504 protected Color selectionColor; 505 protected Color lineHighlightColor; 506 protected Color bracketHighlightColor; 507 protected Color eolMarkerColor; 508 509 protected boolean blockCaret; 510 protected boolean lineHighlight; 511 protected boolean bracketHighlight; 512 protected boolean paintInvalid; 513 protected boolean eolMarkers; 514 protected int cols; 515 protected int rows; 516 517 protected int tabSize; 518 protected FontMetrics fm; 519 520 protected Highlight highlights; 521 522 protected void paintLine(Graphics gfx, TokenMarker tokenMarker, 523 int line, int x) 524 { 525 Font defaultFont = getFont(); 526 Color defaultColor = getForeground(); 527 528 currentLineIndex = line; 529 int y = textArea.lineToY(line); 530 531 if(line < 0 || line >= textArea.getLineCount()) 532 { 533 if(paintInvalid) 534 { 535 paintHighlight(gfx,line,y); 536 styles[Token.INVALID].setGraphicsFlags(gfx,defaultFont); 537 gfx.drawString("~",0,y + fm.getHeight()); 538 } 539 } 540 else if(tokenMarker == null) 541 { 542 paintPlainLine(gfx,line,defaultFont,defaultColor,x,y); 543 } 544 else 545 { 546 paintSyntaxLine(gfx,tokenMarker,line,defaultFont, 547 defaultColor,x,y); 548 } 549 } 550 551 protected void paintPlainLine(Graphics gfx, int line, Font defaultFont, 552 Color defaultColor, int x, int y) 553 { 554 paintHighlight(gfx,line,y); 555 textArea.getLineText(line,currentLine); 556 557 gfx.setFont(defaultFont); 558 gfx.setColor(defaultColor); 559 560 y += fm.getHeight(); 561 x = Utilities.drawTabbedText(currentLine,x,y,gfx,this,0); 562 563 if(eolMarkers) 564 { 565 gfx.setColor(eolMarkerColor); 566 gfx.drawString(".",x,y); 567 } 568 } 569 570 protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker, 571 int line, Font defaultFont, Color defaultColor, int x, int y) 572 { 573 textArea.getLineText(currentLineIndex,currentLine); 574 currentLineTokens = tokenMarker.markTokens(currentLine, 575 currentLineIndex); 576 577 paintHighlight(gfx,line,y); 578 579 gfx.setFont(defaultFont); 580 gfx.setColor(defaultColor); 581 y += fm.getHeight(); 582 x = SyntaxUtilities.paintSyntaxLine(currentLine, 583 currentLineTokens,styles,this,gfx,x,y); 584 585 if(eolMarkers) 586 { 587 gfx.setColor(eolMarkerColor); 588 gfx.drawString(".",x,y); 589 } 590 } 591 592 protected void paintHighlight(Graphics gfx, int line, int y) 593 { 594 if(line >= textArea.getSelectionStartLine() 595 && line <= textArea.getSelectionEndLine()) 596 paintLineHighlight(gfx,line,y); 597 598 if(highlights != null) 599 highlights.paintHighlight(gfx,line,y); 600 601 if(bracketHighlight && line == textArea.getBracketLine()) 602 paintBracketHighlight(gfx,line,y); 603 604 if(line == textArea.getCaretLine()) 605 paintCaret(gfx,line,y); 606 } 607 608 protected void paintLineHighlight(Graphics gfx, int line, int y) 609 { 610 int height = fm.getHeight(); 611 y += fm.getLeading() + fm.getMaxDescent(); 612 613 int selectionStart = textArea.getSelectionStart(); 614 int selectionEnd = textArea.getSelectionEnd(); 615 616 if(selectionStart == selectionEnd) 617 { 618 if(lineHighlight) 619 { 620 gfx.setColor(lineHighlightColor); 621 gfx.fillRect(0,y,getWidth(),height); 622 } 623 } 624 else 625 { 626 gfx.setColor(selectionColor); 627 628 int selectionStartLine = textArea.getSelectionStartLine(); 629 int selectionEndLine = textArea.getSelectionEndLine(); 630 int lineStart = textArea.getLineStartOffset(line); 631 632 int x1, x2; 633 if(textArea.isSelectionRectangular()) 634 { 635 int lineLen = textArea.getLineLength(line); 636 x1 = textArea._offsetToX(line,Math.min(lineLen, 637 selectionStart - textArea.getLineStartOffset( 638 selectionStartLine))); 639 x2 = textArea._offsetToX(line,Math.min(lineLen, 640 selectionEnd - textArea.getLineStartOffset( 641 selectionEndLine))); 642 if(x1 == x2) 643 x2++; 644 } 645 else if(selectionStartLine == selectionEndLine) 646 { 647 x1 = textArea._offsetToX(line, 648 selectionStart - lineStart); 649 x2 = textArea._offsetToX(line, 650 selectionEnd - lineStart); 651 } 652 else if(line == selectionStartLine) 653 { 654 x1 = textArea._offsetToX(line, 655 selectionStart - lineStart); 656 x2 = getWidth(); 657 } 658 else if(line == selectionEndLine) 659 { 660 x1 = 0; 661 x2 = textArea._offsetToX(line, 662 selectionEnd - lineStart); 663 } 664 else 665 { 666 x1 = 0; 667 x2 = getWidth(); 668 } 669 670 gfx.fillRect(x1 > x2 ? x2 : x1,y,x1 > x2 ? 672 (x1 - x2) : (x2 - x1),height); 673 } 674 675 } 676 677 protected void paintBracketHighlight(Graphics gfx, int line, int y) 678 { 679 int position = textArea.getBracketPosition(); 680 if(position == -1) 681 return; 682 y += fm.getLeading() + fm.getMaxDescent(); 683 int x = textArea._offsetToX(line,position); 684 gfx.setColor(bracketHighlightColor); 685 gfx.drawRect(x,y,fm.charWidth('(') - 1, 689 fm.getHeight() - 1); 690 } 691 692 protected void paintCaret(Graphics gfx, int line, int y) 693 { 694 if(textArea.isCaretVisible()) 695 { 696 int offset = textArea.getCaretPosition() 697 - textArea.getLineStartOffset(line); 698 int caretX = textArea._offsetToX(line,offset); 699 int caretWidth = ((blockCaret || 700 textArea.isOverwriteEnabled()) ? 701 fm.charWidth('w') : 1); 702 y += fm.getLeading() + fm.getMaxDescent(); 703 int height = fm.getHeight(); 704 705 gfx.setColor(caretColor); 706 707 if(textArea.isOverwriteEnabled()) 708 { 709 gfx.fillRect(caretX,y + height - 1, 710 caretWidth,1); 711 } 712 else 713 { 714 gfx.drawRect(caretX,y,caretWidth, height - 1); 715 } 716 } 717 } 718 } 719 | Popular Tags |