/* * Determine the Y offset for the current row */ private int getOffsetY(int rowStartOffset, FontMetrics fontMetrics) throws BadLocationException { // Get the bounding rectangle of the row Rectangle r = component.modelToView(rowStartOffset); int lineHeight = fontMetrics.getHeight(); int y = r.y + r.height; int descent = 0; // The text needs to be positioned above the bottom of the bounding // rectangle based on the descent of the font(s) contained on the row. if (r.height == lineHeight) { // default font is being used descent = fontMetrics.getDescent(); } else { // We need to check all the attributes for font changes if (fonts == null) { fonts = new HashMap<String, FontMetrics>(); } Element root = component.getDocument().getDefaultRootElement(); int index = root.getElementIndex(rowStartOffset); Element line = root.getElement(index); for (int i = 0; i < line.getElementCount(); i++) { Element child = line.getElement(i); AttributeSet as = child.getAttributes(); String fontFamily = (String) as.getAttribute(StyleConstants.FontFamily); Integer fontSize = (Integer) as.getAttribute(StyleConstants.FontSize); String key = fontFamily + fontSize; FontMetrics fm = fonts.get(key); if (fm == null) { Font font = new Font(fontFamily, Font.PLAIN, fontSize); fm = component.getFontMetrics(font); fonts.put(key, fm); } descent = Math.max(descent, fm.getDescent()); } } return y - descent; }
/** * Draw the line numbers * * @param g */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); ((Graphics2D) g) .setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Determine the width of the space available to draw the line number FontMetrics fontMetrics = component.getFontMetrics(component.getFont()); Insets insets = getInsets(); int availableWidth = getSize().width - insets.left - insets.right; // Determine the rows to draw within the clipped bounds. Rectangle clip = g.getClipBounds(); int rowStartOffset = component.viewToModel(new Point(0, clip.y)); int endOffset = component.viewToModel(new Point(0, clip.y + clip.height)); while (rowStartOffset <= endOffset) { try { if (isCurrentLine(rowStartOffset)) g.setColor(getCurrentLineForeground()); else g.setColor(getForeground()); // Get the line number as a string and then determine the // "X" and "Y" offsets for drawing the string. String lineNumber = getTextLineNumber(rowStartOffset); int stringWidth = fontMetrics.stringWidth(lineNumber); int x = getOffsetX(availableWidth, stringWidth) + insets.left; int y = getOffsetY(rowStartOffset, fontMetrics); g.drawString(lineNumber, x, y); // Move to the next row rowStartOffset = Utilities.getRowEnd(component, rowStartOffset) + 1; } catch (Exception e) { break; } } }