📄 textareapainter.java
字号:
*
* @param font The font
*/
public final void setFont (final Font font)
{
super.setFont(font);
fm = this.getFontMetrics(font);
textArea.recalculateVisibleLines();
}
/**
* Repaints the text.
*
* @param g The graphics context
*/
public final void paint (final Graphics gfx)
{
tabSize = fm.charWidth(' ') * ((Integer) textArea
.getDocument().getProperty(PlainDocument.tabSizeAttribute)).intValue();
final Rectangle clipRect = gfx.getClipBounds();
gfx.setColor(getBackground());
gfx.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
// We don't use yToLine() here because that method doesn't
// return lines past the end of the document
final int height = fm.getHeight();
final int firstLine = textArea.getFirstLine();
final int firstInvalid = firstLine + clipRect.y / height;
// Because the clipRect's height is usually an even multiple
// of the font height, we subtract 1 from it, otherwise one
// too many lines will always be painted.
final int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height;
try
{
final TokenMarker tokenMarker = textArea.getDocument()
.getTokenMarker();
final int x = textArea.getHorizontalOffset();
for (int line = firstInvalid; line <= lastInvalid; line++)
{
paintLine(gfx, tokenMarker, line, x);
}
if (tokenMarker != null && tokenMarker.isNextLineRequested())
{
final int h = clipRect.y + clipRect.height;
repaint(0, h, getWidth(), getHeight() - h);
}
}
catch (Exception e)
{
System.err.println("Error repainting line"
+ " range {" + firstInvalid + ","
+ lastInvalid + "}:");
e.printStackTrace();
}
}
/**
* Marks a line as needing a repaint.
*
* @param line The line to invalidate
*/
public final void invalidateLine (final int line)
{
repaint(0, textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(),
getWidth(), fm.getHeight());
}
/**
* Marks a range of lines as needing a repaint.
*
* @param firstLine The first line to invalidate
* @param lastLine The last line to invalidate
*/
public final void invalidateLineRange (final int firstLine, final int lastLine)
{
repaint(0, textArea.lineToY(firstLine) + fm.getMaxDescent() + fm.getLeading(),
getWidth(), (lastLine - firstLine + 1) * fm.getHeight());
}
/**
* Repaints the lines containing the selection.
*/
public final void invalidateSelectedLines ()
{
invalidateLineRange(textArea.getSelectionStartLine(),
textArea.getSelectionEndLine());
}
/**
* Implementation of TabExpander interface. Returns next tab stop after a specified
* point.
*
* @param x The x co-ordinate
* @param tabOffset Ignored
* @return The next tab stop after <i>x</i>
*/
public final float nextTabStop (final float x, final int tabOffset)
{
final int offset = textArea.getHorizontalOffset();
final int ntabs = ((int) x - offset) / tabSize;
return (ntabs + 1) * tabSize + offset;
}
/**
* Returns the painter's preferred size.
*/
public final Dimension getPreferredSize ()
{
final Dimension dim = new Dimension();
dim.width = fm.charWidth('w') * cols;
dim.height = fm.getHeight() * rows;
return dim;
}
/**
* Returns the painter's minimum size.
*/
public final Dimension getMinimumSize ()
{
return getPreferredSize();
}
// package-private members
int currentLineIndex;
Token currentLineTokens;
private final Segment currentLine;
// protected members
private final JEditTextArea textArea;
private SyntaxStyle[] styles;
private Color caretColor;
private Color selectionColor;
private Color lineHighlightColor;
private Color bracketHighlightColor;
private Color eolMarkerColor;
private boolean blockCaret;
private boolean lineHighlight;
private boolean bracketHighlight;
private boolean paintInvalid;
private boolean eolMarkers;
private final int cols;
private final int rows;
private int tabSize;
private FontMetrics fm;
private Highlight highlights;
private void paintLine (final Graphics gfx, final TokenMarker tokenMarker,
final int line, final int x)
{
final Font defaultFont = getFont();
final Color defaultColor = getForeground();
currentLineIndex = line;
final int y = textArea.lineToY(line);
if (line < 0 || line >= textArea.getLineCount())
{
if (paintInvalid)
{
paintHighlight(gfx, line, y);
styles[Token.INVALID].setGraphicsFlags(gfx, defaultFont);
gfx.drawString("~", 0, y + fm.getHeight());
}
}
else if (tokenMarker == null)
{
paintPlainLine(gfx, line, defaultFont, defaultColor, x, y);
}
else
{
paintSyntaxLine(gfx, tokenMarker, line, defaultFont,
defaultColor, x, y);
}
}
private void paintPlainLine (final Graphics gfx, final int line, final Font defaultFont,
final Color defaultColor, int x, int y)
{
paintHighlight(gfx, line, y);
textArea.getLineText(line, currentLine);
gfx.setFont(defaultFont);
gfx.setColor(defaultColor);
y += fm.getHeight();
x = Utilities.drawTabbedText(currentLine, x, y, gfx, this, 0);
if (eolMarkers)
{
gfx.setColor(eolMarkerColor);
gfx.drawString(".", x, y);
}
}
private void paintSyntaxLine (final Graphics gfx, final TokenMarker tokenMarker,
final int line, final Font defaultFont,
final Color defaultColor, int x, int y)
{
textArea.getLineText(currentLineIndex, currentLine);
currentLineTokens = tokenMarker.markTokens(currentLine,
currentLineIndex);
paintHighlight(gfx, line, y);
gfx.setFont(defaultFont);
gfx.setColor(defaultColor);
y += fm.getHeight();
x = SyntaxUtilities.paintSyntaxLine(currentLine,
currentLineTokens, styles, this, gfx, x, y);
if (eolMarkers)
{
gfx.setColor(eolMarkerColor);
gfx.drawString(".", x, y);
}
}
private void paintHighlight (final Graphics gfx, final int line, final int y)
{
if (line >= textArea.getSelectionStartLine()
&& line <= textArea.getSelectionEndLine())
{
paintLineHighlight(gfx, line, y);
}
if (highlights != null)
{
highlights.paintHighlight(gfx, line, y);
}
if (bracketHighlight && line == textArea.getBracketLine())
{
paintBracketHighlight(gfx, line, y);
}
if (line == textArea.getCaretLine())
{
paintCaret(gfx, line, y);
}
}
private void paintLineHighlight (final Graphics gfx, final int line, int y)
{
final int height = fm.getHeight();
y += fm.getLeading() + fm.getMaxDescent();
final int selectionStart = textArea.getSelectionStart();
final int selectionEnd = textArea.getSelectionEnd();
if (selectionStart == selectionEnd)
{
if (lineHighlight)
{
gfx.setColor(lineHighlightColor);
gfx.fillRect(0, y, getWidth(), height);
}
}
else
{
gfx.setColor(selectionColor);
final int selectionStartLine = textArea.getSelectionStartLine();
final int selectionEndLine = textArea.getSelectionEndLine();
final int lineStart = textArea.getLineStartOffset(line);
final int x1;
int x2;
if (textArea.isSelectionRectangular())
{
final int lineLen = textArea.getLineLength(line);
x1 = textArea._offsetToX(line, Math.min(lineLen,
selectionStart - textArea.getLineStartOffset(selectionStartLine)));
x2 = textArea._offsetToX(line, Math.min(lineLen,
selectionEnd - textArea.getLineStartOffset(selectionEndLine)));
if (x1 == x2)
{
x2++;
}
}
else if (selectionStartLine == selectionEndLine)
{
x1 = textArea._offsetToX(line,
selectionStart - lineStart);
x2 = textArea._offsetToX(line,
selectionEnd - lineStart);
}
else if (line == selectionStartLine)
{
x1 = textArea._offsetToX(line,
selectionStart - lineStart);
x2 = getWidth();
}
else if (line == selectionEndLine)
{
x1 = 0;
x2 = textArea._offsetToX(line,
selectionEnd - lineStart);
}
else
{
x1 = 0;
x2 = getWidth();
}
// "inlined" min/max()
gfx.fillRect(x1 > x2 ? x2 : x1, y, x1 > x2 ?
(x1 - x2) : (x2 - x1), height);
}
}
private void paintBracketHighlight (final Graphics gfx, final int line, int y)
{
final int position = textArea.getBracketPosition();
if (position == -1)
{
return;
}
y += fm.getLeading() + fm.getMaxDescent();
final int x = textArea._offsetToX(line, position);
gfx.setColor(bracketHighlightColor);
// Hack!!! Since there is no fast way to get the character
// from the bracket matching routine, we use ( since all
// brackets probably have the same width anyway
gfx.drawRect(x, y, fm.charWidth('(') - 1,
fm.getHeight() - 1);
}
private void paintCaret (final Graphics gfx, final int line, int y)
{
if (textArea.isCaretVisible())
{
final int offset = textArea.getCaretPosition()
- textArea.getLineStartOffset(line);
final int caretX = textArea._offsetToX(line, offset);
final int caretWidth = ((blockCaret ||
textArea.isOverwriteEnabled()) ?
fm.charWidth('w') : 1);
y += fm.getLeading() + fm.getMaxDescent();
final int height = fm.getHeight();
gfx.setColor(caretColor);
if (textArea.isOverwriteEnabled())
{
gfx.fillRect(caretX, y + height - 1,
caretWidth, 1);
}
else
{
gfx.drawRect(caretX, y, caretWidth - 1, height - 1);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -