in src/syntaxhighlight/JTextComponentRowHeader.java [279:359]
public void paint(Graphics g) {
super.paint(g);
// check whether the height of this panel matches the height of the text component or not
Dimension textComponentPreferredSize = textComponent.getPreferredSize();
if (textComponentHeight != textComponentPreferredSize.height) {
textComponentHeight = textComponentPreferredSize.height;
updatePanelSize();
}
JViewport viewport = scrollPane.getViewport();
Point viewPosition = viewport.getViewPosition();
Dimension viewportSize = viewport.getSize();
validateTextComponentDocument();
Element defaultRootElement = document.getDefaultRootElement();
// maybe able to get the value when font changed and cache them
// however i'm not sure if there is any condition which will make the java.awt.FontMetrics get by getFontMetrics() from java.awt.Graphics is different from getFontMetrics() from java.awt.Component
FontMetrics fontMetrics = g.getFontMetrics(getFont());
int fontHeight = fontMetrics.getHeight();
int fontAscent = fontMetrics.getAscent();
int fontLeading = fontMetrics.getLeading();
FontMetrics textPaneFontMetrics = g.getFontMetrics(textComponent.getFont());
int textPaneFontHeight = textPaneFontMetrics.getHeight();
// get the location of the document of the left top and right bottom point of the visible part of the text component
int documentOffsetStart = textComponent.viewToModel(viewPosition);
int documentOffsetEnd = textComponent.viewToModel(new Point(viewPosition.x + viewportSize.width, viewPosition.y + viewportSize.height));
// convert the location to line number
int startLine = defaultRootElement.getElementIndex(documentOffsetStart) + 1 + lineNumberOffset;
int endLine = defaultRootElement.getElementIndex(documentOffsetEnd) + 1 + lineNumberOffset;
// draw right border
g.setColor(borderColor);
g.fillRect(panelWidth - borderWidth, viewPosition.y, borderWidth, viewportSize.height);
// draw line number
int startY = -1, baselineOffset = -1;
try {
startY = textComponent.modelToView(documentOffsetStart).y;
baselineOffset = (textPaneFontHeight / 2) + fontAscent - (fontHeight / 2) + fontLeading;
} catch (BadLocationException ex) {
LOG.log(Level.WARNING, null, ex);
return;
}
// text anti-aliasing
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntiAliasing);
// preserve the foreground color (for recover the color after highlighing the line)
Color foregroundColor = getForeground();
g.setColor(foregroundColor);
g.setFont(getFont());
for (int i = startLine, y = startY + baselineOffset; i <= endLine; y += textPaneFontHeight, i++) {
boolean highlighted = false;
if (highlightedLineList.indexOf((Integer) i) != -1) {
// highlight this line
g.setColor(borderColor);
g.fillRect(0, y - baselineOffset, panelWidth - borderWidth, textPaneFontHeight);
g.setColor(highlightedColor);
highlighted = true;
}
// draw the line number
String lineNumberString = Integer.toString(i);
int lineNumberStringWidth = fontMetrics.stringWidth(lineNumberString);
g.drawString(lineNumberString, panelWidth - lineNumberStringWidth - paddingRight, y);
// restore the line number text color
if (highlighted) {
g.setColor(foregroundColor);
}
}
}