Gridarta Editor
TextAreaPainter.java
Go to the documentation of this file.
1 /*
2  * TextAreaPainter.java - Paints the text area
3  * Copyright (C) 1999 Slava Pestov
4  * Copyright (C) 2000-2015 The Gridarta Developers.
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 package net.sf.gridarta.textedit.textarea;
12 
13 import java.awt.Color;
14 import java.awt.Cursor;
15 import java.awt.Dimension;
16 import java.awt.Font;
17 import java.awt.FontMetrics;
18 import java.awt.Graphics;
19 import java.awt.Rectangle;
20 import java.awt.font.FontRenderContext;
21 import java.awt.font.TextLayout;
22 import java.util.Collections;
23 import java.util.LinkedList;
24 import java.util.List;
25 import javax.swing.JComponent;
26 import javax.swing.ToolTipManager;
27 import javax.swing.text.Segment;
28 import javax.swing.text.TabExpander;
29 import javax.swing.text.Utilities;
31 import org.apache.log4j.Category;
32 import org.apache.log4j.Logger;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35 
42 public class TextAreaPainter extends JComponent implements TabExpander {
43 
47  private static final Category LOG = Logger.getLogger(TextAreaPainter.class);
48 
52  private static final long serialVersionUID = 1L;
53 
57  private final FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
58 
63  private final JEditTextArea textArea;
64 
65  @NotNull
67 
68  @NotNull
69  private final TextAreaCaret caret;
70 
74  @NotNull
75  private final TextAreaBrackets brackets;
76 
80  @NotNull
81  private final TextAreaConfig config;
82 
87  private final boolean blockCaret;
88 
93 
98  private final int cols;
99 
104  private final int rows;
105 
110  private final Color caretColor;
111 
116  private final Color selectionColor;
117 
122  private final Color lineHighlightColor;
123 
128  private final boolean lineHighlight;
129 
134  private final Color bracketHighlightColor;
135 
140  private final boolean bracketHighlight;
141 
146  private final boolean paintInvalid;
147 
152  @NotNull
153  private final Color eolMarkerColor;
154 
159  private final boolean eolMarkers;
160 
165  private int currentLineIndex = -1;
166 
170  @Nullable
171  private List<Token> currentLineTokens;
172 
176  @NotNull
177  private final Segment currentLine = new Segment();
178 
183  private int tabSize;
184 
189  @Nullable
190  private FontMetrics fontMetrics;
191 
198  @Nullable
199  private Font defaultFont;
200 
206  private int defaultLineHeight;
207 
213  private int defaultCharWidth;
214 
215  private int visibleLines;
216 
217  private int firstLine;
218 
219  private int horizontalOffset;
220 
221  @NotNull
222  private final Segment lineSegment = new Segment();
223 
233  public TextAreaPainter(@NotNull final JEditTextArea textArea, @NotNull final TextAreaSelection selection, @NotNull final TextAreaCaret caret, @NotNull final TextAreaDefaults defaults, @NotNull final TextAreaBrackets brackets, @NotNull final TextAreaConfig config, final boolean paintInvalid) {
234  this.textArea = textArea;
235  this.selection = selection;
236  this.caret = caret;
237  this.brackets = brackets;
238  this.config = config;
239 
240  setAutoscrolls(true);
241  setDoubleBuffered(true);
242  setOpaque(true);
243 
244  ToolTipManager.sharedInstance().registerComponent(this);
245 
246  setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
247 
248  final Font font = new Font("Monospaced", Font.PLAIN, 14);
249  super.setFont(font);
250  fontMetrics = getFontMetrics(font);
251  setForeground(Color.black);
252  setBackground(Color.white);
253 
254  blockCaret = defaults.getBlockCaret();
255  styles = defaults.getStyles();
256  cols = defaults.getCols();
257  rows = defaults.getRows();
258  caretColor = defaults.getCaretColor();
259  selectionColor = defaults.getSelectionColor();
260  lineHighlightColor = defaults.getLineHighlightColor();
261  lineHighlight = defaults.getLineHighlight();
262  bracketHighlightColor = defaults.getBracketHighlightColor();
263  bracketHighlight = defaults.getBracketHighlight();
264  this.paintInvalid = paintInvalid;
265  eolMarkerColor = defaults.getEolMarkerColor();
266  eolMarkers = defaults.getEolMarkers();
267  }
268 
273  private void updateLineInfo() {
274  final Font font = getFont();
275  if (defaultFont != null && defaultFont.equals(font)) {
276  return;
277  }
278 
279  defaultCharWidth = (int) Math.round((double) new TextLayout("WgGhdJj", font, fontRenderContext).getAdvance() / 7.0);
280  defaultLineHeight = Math.round(font.getLineMetrics("WgGhdJj", fontRenderContext).getHeight());
281  defaultFont = font;
282  }
283 
289  public int getDefaultLineHeight() {
290  updateLineInfo();
291  return defaultLineHeight;
292  }
293 
299  public int getDefaultCharWidth() {
300  updateLineInfo();
301  return defaultCharWidth;
302  }
303 
309  @NotNull
311  return styles;
312  }
313 
319  public void setStyles(@NotNull final SyntaxStyles styles) {
320  this.styles = styles;
321  repaint();
322  }
323 
330  public boolean isBracketHighlightEnabled() {
331  return bracketHighlight;
332  }
333 
338  public boolean isBlockCaretEnabled() {
339  return blockCaret;
340  }
341 
346  @Nullable
347  public FontMetrics getFontMetrics() {
348  return fontMetrics;
349  }
350 
351  @Override
352  public final void setFont(@NotNull final Font font) {
353  super.setFont(font);
354  fontMetrics = getFontMetrics(font);
356  }
357 
362  @Override
363  public void paint(@NotNull final Graphics g) {
364  tabSize = fontMetrics.charWidth(' ') * 4; // I want 4-space wide tabs
365 
366  final Rectangle clipRectangle = g.getClipBounds();
367 
368  g.setColor(getBackground());
369  g.fillRect(clipRectangle.x, clipRectangle.y, clipRectangle.width, clipRectangle.height);
370 
371  // We don't use yToLine() here because that method doesn't
372  // return lines past the end of the document
373  final int height = fontMetrics.getHeight();
374  final int firstInvalid = firstLine + clipRectangle.y / height;
375  // Because the clipRectangle's height is usually an even multiple
376  // of the font height, we subtract 1 from it, otherwise one
377  // too many lines will always be painted.
378  final int lastInvalid = firstLine + (clipRectangle.y + clipRectangle.height - 1) / height;
379 
380  try {
381  final TokenMarker tokenMarker = selection.getDocument().getTokenMarker();
382 
383  for (int line = firstInvalid; line <= lastInvalid; line++) {
384  paintLine(g, tokenMarker, line, horizontalOffset);
385  }
386 
387  if (tokenMarker != null && tokenMarker.isNextLineRequested()) {
388  final int h = clipRectangle.y + clipRectangle.height;
389  repaint(0, h, getWidth(), getHeight() - h);
390  }
391  } catch (final Exception e) {
392  LOG.error("Error repainting line range {" + firstInvalid + ", " + lastInvalid + "}", e);
393  }
394  }
395 
400  public void invalidateLine(final int line) {
401  repaint(0, lineToY(line) + fontMetrics.getMaxDescent() + fontMetrics.getLeading(), getWidth(), fontMetrics.getHeight());
402  }
403 
409  public void invalidateLineRange(final int firstLine, final int lastLine) {
410  repaint(0, lineToY(firstLine) + fontMetrics.getMaxDescent() + fontMetrics.getLeading(), getWidth(), (lastLine - firstLine + 1) * fontMetrics.getHeight());
411  }
412 
416  public void invalidateSelectedLines() {
418  }
419 
420  @Override
421  public float nextTabStop(final float x, final int tabOffset) {
422  final int nTabs = ((int) x - horizontalOffset) / tabSize;
423  return (float) ((nTabs + 1) * tabSize + horizontalOffset);
424  }
425 
426  @NotNull
427  @Override
428  public Dimension getPreferredSize() {
429  final Dimension dim = super.getPreferredSize();
430  return dim != null ? dim : newDimension(cols, rows);
431  }
432 
433  @NotNull
434  @Override
435  public Dimension getMinimumSize() {
436  final Dimension dim = super.getMinimumSize();
437  return dim != null ? dim : newDimension(1, 1);
438  }
439 
446  @NotNull
447  private Dimension newDimension(final int columns, final int rows) {
448  return new Dimension(columns * fontMetrics.charWidth('w'), rows * fontMetrics.getHeight());
449  }
450 
458  private void paintLine(@NotNull final Graphics gfx, @Nullable final TokenMarker tokenMarker, final int line, final int x) {
459  final Font font = getFont();
460  final Color foreground = getForeground();
461 
462  currentLineIndex = line;
463  final int y = lineToY(line);
464 
465  if (line < 0 || line >= selection.getLineCount()) {
466  if (paintInvalid) {
467  paintHighlight(gfx, line, y);
468  styles.getStyle(Token.INVALID).setGraphicsFlags(gfx, font);
469  gfx.drawString("~", 0, y + fontMetrics.getHeight());
470  }
471  } else if (tokenMarker == null) {
472  paintPlainLine(gfx, line, font, foreground, x, y);
473  } else {
474  paintSyntaxLine(gfx, tokenMarker, line, font, foreground, x, y);
475  }
476  }
477 
487  private void paintPlainLine(@NotNull final Graphics gfx, final int line, @NotNull final Font defaultFont, @NotNull final Color defaultColor, final int x, final int y) {
488  paintHighlight(gfx, line, y);
489  selection.getLineText(line, currentLine);
490 
491  gfx.setFont(defaultFont);
492  gfx.setColor(defaultColor);
493 
494  final int yy = y + fontMetrics.getHeight();
495  final int xx = Utilities.drawTabbedText(currentLine, x, yy, gfx, this, 0);
496 
497  if (eolMarkers) {
498  gfx.setColor(eolMarkerColor);
499  gfx.drawString(".", xx, yy);
500  }
501  }
502 
513  private void paintSyntaxLine(@NotNull final Graphics gfx, @NotNull final TokenMarker tokenMarker, final int line, @NotNull final Font defaultFont, @NotNull final Color defaultColor, final int x, final int y) {
514  selection.getLineText(currentLineIndex, currentLine);
515  currentLineTokens = tokenMarker.markTokens(currentLine, currentLineIndex);
516 
517  paintHighlight(gfx, line, y);
518 
519  gfx.setFont(defaultFont);
520  gfx.setColor(defaultColor);
521  final int yy = y + fontMetrics.getHeight();
522  final int xx = SyntaxUtilities.paintSyntaxLine(currentLine, currentLineTokens, styles, this, gfx, x, yy);
523 
524  if (eolMarkers) {
525  // draw End-Of-Line markers, if enabled
526  gfx.setColor(eolMarkerColor);
527  gfx.drawString(".", xx, yy);
528  }
529  }
530 
538  private void paintHighlight(@NotNull final Graphics gfx, final int line, final int y) {
539  if (line >= selection.getSelectionStartLine() && line <= selection.getSelectionEndLine()) {
540  paintLineHighlight(gfx, line, y);
541  }
542 
543  if (bracketHighlight && line == brackets.getBracketLine()) {
544  paintBracketHighlight(gfx, line, y);
545  }
546 
547  if (line == selection.getCaretLine()) {
548  paintCaret(gfx, line, y); // CARET gets drawn at this point (if currently visible)
549  }
550  }
551 
558  private void paintLineHighlight(@NotNull final Graphics gfx, final int line, final int y) {
559  final int height = fontMetrics.getHeight();
560  final int yy = y + fontMetrics.getLeading() + fontMetrics.getMaxDescent();
561 
562  final int selectionStart = selection.getSelectionStart();
563  final int selectionEnd = selection.getSelectionEnd();
564 
565  if (selectionStart == selectionEnd) {
566  if (lineHighlight) {
567  gfx.setColor(lineHighlightColor);
568  gfx.fillRect(0, yy, getWidth(), height);
569  }
570  } else {
571  gfx.setColor(selectionColor);
572 
573  final int selectionStartLine = selection.getSelectionStartLine();
574  final int selectionEndLine = selection.getSelectionEndLine();
575  final int lineStart = selection.getLineStartOffset(line);
576 
577  final int x1;
578  final int x2;
579  if (selection.isSelectionRectangular()) {
580  final int lineLen = selection.getLineLength(line);
581  x1 = offsetToX2(line, Math.min(lineLen, selectionStart - selection.getLineStartOffset(selectionStartLine)));
582  final int x3 = offsetToX2(line, Math.min(lineLen, selectionEnd - selection.getLineStartOffset(selectionEndLine)));
583  x2 = x3 + (x1 == x3 ? 1 : 0);
584  } else if (selectionStartLine == selectionEndLine) {
585  x1 = offsetToX2(line, selectionStart - lineStart);
586  x2 = offsetToX2(line, selectionEnd - lineStart);
587  } else if (line == selectionStartLine) {
588  x1 = offsetToX2(line, selectionStart - lineStart);
589  x2 = getWidth();
590  } else if (line == selectionEndLine) {
591  x1 = 0;
592  x2 = offsetToX2(line, selectionEnd - lineStart);
593  } else {
594  x1 = 0;
595  x2 = getWidth();
596  }
597 
598  gfx.fillRect(Math.min(x1, x2), yy, Math.abs(x1 - x2), height);
599  }
600 
601  }
602 
609  private void paintBracketHighlight(@NotNull final Graphics gfx, final int line, final int y) {
610  final int position = brackets.getBracketPosition();
611  if (position == -1) {
612  return;
613  }
614 
615  final int yy = y + fontMetrics.getLeading() + fontMetrics.getMaxDescent();
616  final int xx = offsetToX2(line, position);
617  gfx.setColor(bracketHighlightColor);
618  // Hack!!! Since there is no fast way to get the character
619  // from the bracket matching routine, we use ( since all
620  // brackets probably have the same width anyway
621  gfx.drawRect(xx, yy, fontMetrics.charWidth('(') - 1, fontMetrics.getHeight() - 1);
622  }
623 
630  private void paintCaret(@NotNull final Graphics gfx, final int line, final int y) {
631  if (caret.isCaretVisible()) {
632  final int offset = selection.getCaretPosition() - selection.getLineStartOffset(line);
633  final int caretX = offsetToX2(line, offset);
634  final int caretWidth = blockCaret || config.isOverwrite() ? fontMetrics.charWidth('w') : 1;
635  final int yy = y + fontMetrics.getLeading() + fontMetrics.getMaxDescent();
636  final int height = fontMetrics.getHeight();
637 
638  gfx.setColor(caretColor);
639 
640  if (config.isOverwrite()) {
641  gfx.fillRect(caretX, yy + height - 1, caretWidth, 1);
642  } else {
643  if (caretWidth <= 1) {
644  // This special case is very important: If 'caretWidth = 1' below rectangle would
645  // have zero width. With JDK 1.4.1, such a rectangle with zero width does not get drawn,
646  // which leads to incredible problems. (Damn this was hard to figure out!)
647  gfx.drawLine(caretX, yy, caretX, yy + height - 1);
648  } else {
649  gfx.drawRect(caretX, yy, caretWidth - 1, height - 1);
650  }
651  }
652  }
653  }
654 
659  public int getCurrentLineIndex() {
660  return currentLineIndex;
661  }
662 
667  public void setCurrentLineIndex(final int lineIndex) {
668  currentLineIndex = lineIndex;
669  }
670 
675  @Nullable
676  public List<Token> getCurrentLineTokens() {
677  return currentLineTokens == null ? null : Collections.unmodifiableList(currentLineTokens);
678  }
679 
684  public void setCurrentLineTokens(@Nullable final List<Token> tokens) {
685  currentLineTokens = tokens == null ? null : new LinkedList<>(tokens);
686  }
687 
692  public void recalculateVisibleLines() {
693  final int height = getHeight();
694 
695  // get line height
696  final int lineHeight;
697  if (fontMetrics == null) {
698  lineHeight = getDefaultLineHeight(); // default height might be wrong, take it only when needed
699  } else {
700  lineHeight = fontMetrics.getHeight();
701  }
702 
703  visibleLines = height / lineHeight;
704  textArea.updateScrollBars();
705  }
706 
707  public int getVisibleLines() {
708  return visibleLines;
709  }
710 
714  public int getFirstLine() {
715  return firstLine;
716  }
717 
718  public boolean setFirstLine(final int firstLine) {
719  if (firstLine == this.firstLine) {
720  return false;
721  }
722 
723  this.firstLine = firstLine;
724  return true;
725  }
726 
731  public int lineToY(final int line) {
732  return (line - firstLine) * fontMetrics.getHeight() - (fontMetrics.getLeading() + fontMetrics.getMaxDescent());
733  }
734 
738  public int getHorizontalOffset() {
739  return horizontalOffset;
740  }
741 
742  public boolean setHorizontalOffset(final int horizontalOffset) {
743  if (this.horizontalOffset == horizontalOffset) {
744  return false;
745  }
746 
747  this.horizontalOffset = horizontalOffset;
748  return true;
749  }
750 
758  public int offsetToX2(final int line, final int offset) {
759  final TokenMarker tokenMarker = selection.getTokenMarker();
760 
761  /* Use painter's cached info for speed */
762  FontMetrics fm = fontMetrics;
763 
764  selection.getLineText(line, lineSegment);
765 
766  final int segmentOffset = lineSegment.offset;
767  int x = horizontalOffset;
768 
769  /* If syntax coloring is disabled, do simple translation */
770  if (tokenMarker == null) {
771  lineSegment.count = offset;
772  return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, this, 0);
773  } else {
774  /* If syntax coloring is enabled, we have to do this because
775  * tokens can vary in width */
776  final List<Token> tokens;
777  if (currentLineIndex == line && getCurrentLineTokens() != null) {
778  tokens = getCurrentLineTokens();
779  } else {
780  currentLineIndex = line;
781  tokens = tokenMarker.markTokens(lineSegment, line);
782  setCurrentLineTokens(tokens);
783  }
784 
785  final Font defaultFont = getFont();
786  for (final Token token : tokens) {
787  final byte id = token.getId();
788  if (id == Token.NULL) {
789  fm = fontMetrics;
790  } else {
791  fm = styles.getStyle(id).getFontMetrics(defaultFont, getGraphics());
792  }
793 
794  final int length = token.getLength();
795 
796  if (offset + segmentOffset < lineSegment.offset + length) {
797  lineSegment.count = offset - (lineSegment.offset - segmentOffset);
798  return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, this, 0);
799  }
800  lineSegment.count = length;
801  x += Utilities.getTabbedTextWidth(lineSegment, fm, x, this, 0);
802  lineSegment.offset += length;
803  }
804  return x;
805  }
806  }
807 
814  public int offsetToX(final int line, final int offset) {
815  // don't use cached tokens
816  setCurrentLineTokens(null);
817  return offsetToX2(line, offset);
818  }
819 
824  public int yToLine(final int y) {
825  final FontMetrics fm = fontMetrics;
826  final int height = fm.getHeight();
827  return Math.max(0, Math.min(selection.getLineCount() - 1, y / height + firstLine));
828  }
829 
835  public int xToOffset(final int line, final int x) {
836  final TokenMarker tokenMarker = selection.getTokenMarker();
837 
838  /* Use painter's cached info for speed */
839  FontMetrics fm = fontMetrics;
840 
841  selection.getLineText(line, lineSegment);
842 
843  final char[] segmentArray = lineSegment.array;
844  final int segmentOffset = lineSegment.offset;
845  final int segmentCount = lineSegment.count;
846 
847  int width = horizontalOffset;
848 
849  if (tokenMarker == null) {
850  for (int i = 0; i < segmentCount; i++) {
851  final char c = segmentArray[i + segmentOffset];
852  final int charWidth;
853  if (c == '\t') {
854  charWidth = (int) nextTabStop((float) width, i) - width;
855  } else {
856  charWidth = fm.charWidth(c);
857  }
858 
859  if (blockCaret) {
860  if (x - charWidth <= width) {
861  return i;
862  }
863  } else {
864  if (x - charWidth / 2 <= width) {
865  return i;
866  }
867  }
868 
869  width += charWidth;
870  }
871 
872  return segmentCount;
873  } else {
874  final List<Token> tokens;
875  if (currentLineIndex == line && getCurrentLineTokens() != null) {
876  tokens = getCurrentLineTokens();
877  } else {
878  currentLineIndex = line;
879  tokens = tokenMarker.markTokens(lineSegment, line);
880  setCurrentLineTokens(tokens);
881  }
882 
883  int offset = 0;
884  final Font defaultFont = getFont();
885  for (final Token token : tokens) {
886  final byte id = token.getId();
887  if (id == Token.NULL) {
888  fm = fontMetrics;
889  } else {
890  fm = styles.getStyle(id).getFontMetrics(defaultFont, getGraphics());
891  }
892 
893  final int length = token.getLength();
894 
895  for (int i = 0; i < length; i++) {
896  final char c = segmentArray[segmentOffset + offset + i];
897  final int charWidth;
898  if (c == '\t') {
899  charWidth = (int) nextTabStop((float) width, offset + i) - width;
900  } else {
901  charWidth = fm.charWidth(c);
902  }
903 
904  if (blockCaret) {
905  if (x - charWidth <= width) {
906  return offset + i;
907  }
908  } else {
909  if (x - charWidth / 2 <= width) {
910  return offset + i;
911  }
912  }
913 
914  width += charWidth;
915  }
916 
917  offset += length;
918  }
919  return offset;
920  }
921  }
922 
928  public int xyToOffset(final int x, final int y) {
929  final int line = yToLine(y);
930  final int start = selection.getLineStartOffset(line);
931  return start + xToOffset(line, x);
932  }
933 
934 }
void invalidateSelectedLines()
Repaints the lines containing the selection.
final boolean eolMarkers
Whether end of line markers should be painted.
int defaultLineHeight
The line height of defaultFont.
int getFirstLine()
Returns the line displayed at the text area&#39;s origin.
final void setFont(@NotNull final Font font)
FontMetrics fontMetrics
The font metrics for this instance.
int getSelectionEnd()
Returns the selection end offset.
void paintBracketHighlight(@NotNull final Graphics gfx, final int line, final int y)
Paints the bracket highlight.
boolean isOverwrite()
Returns whether overwrite mode is active.
final Color lineHighlightColor
The color for line highlighting.
void setCurrentLineTokens(@Nullable final List< Token > tokens)
Sets the tokens of the currently painted line.
int getBracketPosition()
Returns the position of the highlighted bracket (the bracket matching the one before the caret)...
void paintPlainLine(@NotNull final Graphics gfx, final int line, @NotNull final Font defaultFont, @NotNull final Color defaultColor, final int x, final int y)
Paint a line without token highlighting.
int getCaretPosition()
Returns the caret position.
void setStyles(@NotNull final SyntaxStyles styles)
Sets the syntax styles used to paint colorized text.
boolean isCaretVisible()
Returns true if the caret is visible, false otherwise.
int getSelectionStart()
Returns the selection start offset.
void paint(@NotNull final Graphics g)
Repaints the text.
SyntaxStyles styles
The syntax styles used to paint colorized text.
A set of SyntaxStyle instances for painting colorized text.
FontMetrics getFontMetrics()
Returns the font metrics used by this component.
void recalculateVisibleLines()
Recalculates the number of visible lines.
void updateScrollBars()
Updates the state of the scroll bars.
float nextTabStop(final float x, final int tabOffset)
final Color eolMarkerColor
The color for painting eol markers.
void paintLine(@NotNull final Graphics gfx, @Nullable final TokenMarker tokenMarker, final int line, final int x)
Paints one line.
int getLineCount()
Returns the number of lines in the document.
void paintCaret(@NotNull final Graphics gfx, final int line, final int y)
Paints the caret highlight.
int getLineLength(final int line)
Returns the length of the specified line.
int getHorizontalOffset()
Returns the horizontal offset of drawn lines.
final TextAreaConfig config
The TextAreaConfig options to use.
boolean isBracketHighlightEnabled()
Returns whether bracket highlighting is enabled.
TokenMarker getTokenMarker()
Returns the document&#39;s token marker.
boolean setHorizontalOffset(final int horizontalOffset)
int xyToOffset(final int x, final int y)
Converts a point to an offset, from the start of the text.
TextAreaPainter(@NotNull final JEditTextArea textArea, @NotNull final TextAreaSelection selection, @NotNull final TextAreaCaret caret, @NotNull final TextAreaDefaults defaults, @NotNull final TextAreaBrackets brackets, @NotNull final TextAreaConfig config, final boolean paintInvalid)
Creates a new repaint manager.
int getDefaultCharWidth()
This works only for fonts with fixed line height.
void setCurrentLineIndex(final int lineIndex)
Sets the currently painted line.
Base package of all Gridarta classes.
TokenMarker getTokenMarker()
Returns the token marker that is to be used to split lines of this document up into tokens...
CharSequence getLineText(final int lineIndex)
Returns the text on the specified line.
Font defaultFont
The Font from which defaultLineHeight and defaultCharWidth have been calculated.
SyntaxStyle getStyle(final byte id)
Returns a style for a token id.
A linked list of tokens.
Definition: Token.java:21
void paintHighlight(@NotNull final Graphics gfx, final int line, final int y)
Adds highlights for a line: selections, custom highlights from client code, brackets, caret.
SyntaxDocument getDocument()
Returns the document this text area is editing.
static final Category LOG
The Logger for printing log messages.
SyntaxStyles getStyles()
Returns the syntax styles used to paint colorized text.
final JEditTextArea textArea
The associated text area that is painted.
int yToLine(final int y)
Converts a y co-ordinate to a line index.
void paintSyntaxLine(@NotNull final Graphics gfx, @NotNull final TokenMarker tokenMarker, final int line, @NotNull final Font defaultFont, @NotNull final Color defaultColor, final int x, final int y)
Paint a line with token highlighting.
final FontRenderContext fontRenderContext
The font render context for this instance.
int getSelectionStartLine()
Returns the selection start line.
Class with several utility functions used by jEdit&#39;s syntax colorizing subsystem. ...
int getDefaultLineHeight()
This works only for fonts with fixed line height.
void invalidateLineRange(final int firstLine, final int lastLine)
Marks a range of lines as needing a repaint.
boolean isBlockCaretEnabled()
Returns whether the caret should be drawn as a block.
Dimension newDimension(final int columns, final int rows)
Returns a Dimension measured in default character sizes.
This package contains the other part of the script editor.
int defaultCharWidth
The character width of defaultFont.
List< Token > markTokens(final Segment line, final int lineIndex)
A wrapper for the lower-level.
int getCurrentLineIndex()
Returns the currently painted line.
final boolean lineHighlight
Whether line highlighting is enabled.
final boolean blockCaret
Whether the caret should be wide even in insert mode.
static final byte NULL
Normal text token id.
Definition: Token.java:26
int offsetToX(final int line, final int offset)
Converts an offset in a line into an x co-ordinate.
final Color bracketHighlightColor
The color for bracket highlighting.
final boolean paintInvalid
Whether invalid lines should be painted as red tildes.
static int paintSyntaxLine(final Segment line, final Iterable< Token > tokens, final SyntaxStyles styles, final TabExpander expander, final Graphics gfx, final int x, final int y)
Paints the specified line onto the graphics context.
int lineToY(final int line)
Converts a line index to a y co-ordinate.
final TextAreaBrackets brackets
The brackets to paint.
A token marker that splits lines of text into tokens.
Maintains information about the highlighted pairs of brackets.
boolean isSelectionRectangular()
Returns true if the selection is rectangular, false otherwise.
List< Token > getCurrentLineTokens()
Returns the tokens of the currently painted line.
int xToOffset(final int line, final int x)
Converts an x co-ordinate to an offset within a line.
int getLineStartOffset(final int line)
Returns the start offset of the specified line.
int currentLineIndex
The currently painted line.
void paintLineHighlight(@NotNull final Graphics gfx, final int line, final int y)
Paints the selection highlight.
boolean isNextLineRequested()
Returns true if the next line should be repainted.
static final long serialVersionUID
The serial version UID.
static final byte INVALID
Invalid token id.
Definition: Token.java:84
void updateLineInfo()
Make sure defaultCharWidth and defaultLineHeight are up-to-date.
final Color selectionColor
The selection color.
Miscellaneous configuration settings for JEditTextArea.
FontMetrics getFontMetrics(final Font font, final Graphics g)
Returns the font metrics for the styled font.
int getBracketLine()
Returns the line of the highlighted bracket (the bracket matching the one before the caret)...
int getSelectionEndLine()
Returns the selection end line.
final Segment currentLine
Holds the currently painted line.
final boolean bracketHighlight
Whether bracket highlighting is enabled.
List< Token > currentLineTokens
The tokens of the currently painted line.
int offsetToX2(final int line, final int offset)
Converts an offset in a line into an x co-ordinate.
Encapsulates default settings for a text area.
void invalidateLine(final int line)
Marks a line as needing a repaint.
void setGraphicsFlags(final Graphics gfx, final Font font)
Sets the text color and font of the specified graphics context to that specified in this style...