📄 textareapainter.java
字号:
/** * Returns the font metrics used by this component. */ public FontMetrics getFontMetrics() { return fm; } /** * Sets the font for this component. This is overridden to update the * cached font metrics and to recalculate which lines are visible. * @param font The font */ public void setFont(Font font) { super.setFont(font); fm = getFontMetrics(font); textArea.recalculateVisibleLines(); updateTabSize(); } /** * Repaints the text. * @param g The graphics context */ public void paintComponent(Graphics gfx) { updateTabSize(); textArea.getTextRenderer().setupGraphics(gfx); Buffer buffer = textArea.getBuffer(); Rectangle clipRect = gfx.getClipBounds(); gfx.setColor(getBackground()); gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height); int x = textArea.getHorizontalOffset(); 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; int lineCount = textArea.getVirtualLineCount(); int y = (clipRect.y - clipRect.y % height); try { int maxWidth = textArea.maxHorizontalScrollWidth; boolean updateMaxHorizontalScrollWidth = false; for(int line = firstInvalid; line <= lastInvalid; line++) { boolean valid = buffer.isLoaded() && line >= 0 && line < lineCount; int physicalLine; if(valid) physicalLine = buffer.virtualToPhysical(line); else { int virtualLineCount = buffer.getVirtualLineCount(); physicalLine = buffer.virtualToPhysical( virtualLineCount - 1) + (line - virtualLineCount); } int width = paintLine(gfx,buffer,valid,line, physicalLine,x,y) - x + 5 /* Yay */; if(valid) { buffer.setLineWidth(physicalLine,width); if(width > maxWidth) updateMaxHorizontalScrollWidth = true; } y += height; } if(buffer.isNextLineRequested()) { int h = clipRect.y + clipRect.height; repaint(0,h,getWidth(),getHeight() - h); } if(updateMaxHorizontalScrollWidth) textArea.updateMaxHorizontalScrollWidth(); } catch(Exception e) { Log.log(Log.ERROR,this,"Error repainting line" + " range {" + firstInvalid + "," + lastInvalid + "}:"); Log.log(Log.ERROR,this,e); } } /** * 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') * 80; dim.height = fm.getHeight() * 25; return dim; } /** * Returns the painter's minimum size. */ public Dimension getMinimumSize() { return getPreferredSize(); } // package-private members void updateTabSize() { if(textArea.getBuffer() == null) return; tabSize = fm.charWidth(' ') * ((Integer)textArea .getBuffer().getProperty( PlainDocument.tabSizeAttribute)).intValue(); int _maxLineLen = ((Integer)textArea.getBuffer() .getProperty("maxLineLen")).intValue(); if(_maxLineLen <= 0) maxLineLen = 0; else maxLineLen = fm.charWidth(' ') * _maxLineLen; } // private members private JEditTextArea textArea; private SyntaxStyle[] styles; private Color caretColor; private Color selectionColor; private Color lineHighlightColor; private Color bracketHighlightColor; private Color eolMarkerColor; private Color wrapGuideColor; private boolean blockCaret; private boolean lineHighlight; private boolean bracketHighlight; private boolean eolMarkers; private boolean wrapGuide; private boolean antiAlias; private boolean fracFontMetrics; private int tabSize; private int maxLineLen; private FontMetrics fm; private TextAreaHighlight highlights; private int paintLine(Graphics gfx, Buffer buffer, boolean valid, int virtualLine, int physicalLine, int x, int y) { paintHighlight(gfx,virtualLine,physicalLine,y,valid); if(maxLineLen != 0 && wrapGuide) { gfx.setColor(wrapGuideColor); gfx.drawLine(x + maxLineLen,y,x + maxLineLen, y + fm.getHeight()); } if(valid) { Font defaultFont = getFont(); Color defaultColor = getForeground(); gfx.setFont(defaultFont); gfx.setColor(defaultColor); int baseLine = y + fm.getHeight() - fm.getLeading() - fm.getDescent(); x = buffer.paintSyntaxLine(physicalLine,gfx,x,baseLine, this,true,true,defaultFont,defaultColor, (lineHighlight && textArea.getSelectionCount() == 0 && physicalLine == textArea.getCaretLine() ? lineHighlightColor : getBackground()),styles, textArea.getTextRenderer()); if(eolMarkers) { gfx.setFont(defaultFont); gfx.setColor(eolMarkerColor); gfx.drawString(".",x,baseLine); } if(physicalLine == textArea.getCaretLine() && textArea.isCaretVisible()) paintCaret(gfx,physicalLine,y); if(buffer.isFoldStart(physicalLine) && !buffer.isLineVisible(physicalLine + 1)) { gfx.setColor(defaultColor); int start = textArea.getHorizontalOffset() + fm.charWidth(' ') * buffer.getFoldLevel(physicalLine); gfx.drawLine(start,y + fm.getHeight() - 1, x - 1,y + fm.getHeight() - 1); } } return x; } private void paintHighlight(Graphics gfx, int virtualLine, int physicalLine, int y, boolean valid) { if(valid) { if(textArea.selection.size() == 0) { if(lineHighlight && physicalLine == textArea.getCaretLine()) { gfx.setColor(lineHighlightColor); gfx.fillRect(0,y,getWidth(),fm.getHeight()); } } else { gfx.setColor(selectionColor); for(int i = textArea.selection.size() - 1; i >= 0; i--) { paintSelection(gfx,physicalLine,y, (Selection)textArea.selection .elementAt(i)); } } if(bracketHighlight && physicalLine == textArea.getBracketLine() && textArea.isHighlightVisible()) paintBracketHighlight(gfx,physicalLine,y); } if(highlights != null) { highlights.paintHighlight(gfx,virtualLine, y - fm.getLeading() - fm.getDescent()); } } private void paintBracketHighlight(Graphics gfx, int physicalLine, int y) { int position = textArea.getBracketPosition(); if(position == -1) return; int x = textArea.offsetToX(physicalLine,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(Graphics gfx, int physicalLine, int y) { int offset = textArea.getCaretPosition() - textArea.getLineStartOffset(physicalLine); int caretX = textArea.offsetToX(physicalLine,offset); int height = fm.getHeight(); gfx.setColor(caretColor); if(textArea.isOverwriteEnabled()) { gfx.drawLine(caretX,y + height - 1, caretX + fm.charWidth('w'),y + height - 1); } else if(blockCaret) { if(textArea.selection == null && lineHighlight) gfx.setXORMode(lineHighlightColor); else gfx.setXORMode(getBackground()); gfx.fillRect(caretX,y,fm.charWidth('w'),height); gfx.setPaintMode(); } else { gfx.drawLine(caretX,y,caretX,y + height - 1); } } private void paintSelection(Graphics gfx, int physicalLine, int y, Selection s) { if(physicalLine < s.startLine || physicalLine > s.endLine) return; int lineStart = textArea.getLineStartOffset(physicalLine); int x1, x2; if(s instanceof Selection.Rect) { int lineLen = textArea.getLineLength(physicalLine); x1 = textArea.offsetToX(physicalLine,Math.min(lineLen, s.start - textArea.getLineStartOffset( s.startLine))); x2 = textArea.offsetToX(physicalLine,Math.min(lineLen, s.end - textArea.getLineStartOffset( s.endLine))); if(x1 > x2) { int tmp = x2; x2 = x1; x1 = tmp; } } else if(s.startLine == s.endLine) { x1 = textArea.offsetToX(physicalLine, s.start - lineStart); x2 = textArea.offsetToX(physicalLine, s.end - lineStart); } else if(physicalLine == s.startLine) { x1 = textArea.offsetToX(physicalLine, s.start - lineStart); x2 = getWidth(); } else if(physicalLine == s.endLine) { x1 = 0; x2 = textArea.offsetToX(physicalLine, s.end - lineStart); } else { x1 = 0; x2 = getWidth(); } if(x1 == x2) x2++; gfx.fillRect(x1,y,x2 - x1,fm.getHeight()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -