📄 textareapainter.java
字号:
*/ public void setFont(Font font) { super.setFont(font); fm = Toolkit.getDefaultToolkit().getFontMetrics(font); textArea.recalculateVisibleLines(); } /** * Repaints the text. * @param g The graphics context */ public void paint(Graphics gfx) { tabSize = fm.charWidth(' ') * ((Integer)textArea .getDocument().getProperty( PlainDocument.tabSizeAttribute)).intValue(); 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 int height = fm.getHeight(); int firstLine = textArea.getFirstLine(); 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. int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; try { TokenMarker tokenMarker = textArea.getDocument() .getTokenMarker(); int x = textArea.getHorizontalOffset(); for(int line = firstInvalid; line <= lastInvalid; line++) { paintLine(gfx,tokenMarker,line,x); } if(tokenMarker != null && tokenMarker.isNextLineRequested()) { 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(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(int firstLine, 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 float nextTabStop(float x, int tabOffset) { int offset = textArea.getHorizontalOffset(); int ntabs = ((int)x - offset) / tabSize; return (ntabs + 1) * tabSize + offset; } /** * Returns the painter's preferred size. */ public Dimension getPreferredSize() { Dimension dim = new Dimension(); dim.width = fm.charWidth('w') * cols; dim.height = fm.getHeight() * rows; return dim; } /** * Returns the painter's minimum size. */ public Dimension getMinimumSize() { return getPreferredSize(); } // package-private members int currentLineIndex; Token currentLineTokens; Segment currentLine; // protected members protected JEditTextArea textArea; protected SyntaxStyle[] styles; protected Color caretColor; protected Color selectionColor; protected Color lineHighlightColor; protected Color bracketHighlightColor; protected Color eolMarkerColor; protected boolean blockCaret; protected boolean lineHighlight; protected boolean bracketHighlight; protected boolean paintInvalid; protected boolean eolMarkers; protected int cols; protected int rows; protected int tabSize; protected FontMetrics fm; protected Highlight highlights; protected void paintLine(Graphics gfx, TokenMarker tokenMarker, int line, int x) { Font defaultFont = getFont(); Color defaultColor = getForeground(); currentLineIndex = line; 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); } } protected void paintPlainLine(Graphics gfx, int line, Font defaultFont, 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); } } protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker, int line, Font defaultFont, 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); } } protected void paintHighlight(Graphics gfx, int line, 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); } protected void paintLineHighlight(Graphics gfx, int line, int y) { int height = fm.getHeight(); y += fm.getLeading() + fm.getMaxDescent(); int selectionStart = textArea.getSelectionStart(); int selectionEnd = textArea.getSelectionEnd(); if(selectionStart == selectionEnd) { if(lineHighlight) { gfx.setColor(lineHighlightColor); gfx.fillRect(0,y,getWidth(),height); } } else { gfx.setColor(selectionColor); int selectionStartLine = textArea.getSelectionStartLine(); int selectionEndLine = textArea.getSelectionEndLine(); int lineStart = textArea.getLineStartOffset(line); int x1, x2; if(textArea.isSelectionRectangular()) { 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); } } protected void paintBracketHighlight(Graphics gfx, int line, int y) { int position = textArea.getBracketPosition(); if(position == -1) return; y += fm.getLeading() + fm.getMaxDescent(); 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); }protected void paintCaret(Graphics gfx, int line, int y) { if(textArea.isCaretVisible()) { int offset = textArea.getCaretPosition() - textArea.getLineStartOffset(line); int caretX = textArea._offsetToX(line,offset); int caretWidth = ((blockCaret || textArea.isOverwriteEnabled()) ? fm.charWidth('w') : 1); y += fm.getLeading() + fm.getMaxDescent(); int height = fm.getHeight(); gfx.setColor(caretColor); if(textArea.isOverwriteEnabled()) { gfx.fillRect(caretX,y + height - 1, caretWidth,1); } else { gfx.drawRect(caretX,y,caretWidth, height - 1); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -