kamalchopra / jsyntaxpane

Automatically exported from code.google.com/p/jsyntaxpane
0 stars 0 forks source link

The LineNumbersRuler class does not work as expected #41

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
1) It displays line numbers for lines that don't exist (in fact for the
entire height of the JScrollPane)
2) It does not support setting the background color

My suggestion to implement these features:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.JTextComponent;

public class LineNumberComponent extends JComponent implements CaretListener {

  /** Need to correct the y position of line number text for better support
of custom L&F. */
  private int positionCorrector;

  private JTextComponent pane;
  private String format;
  public static final int R_MARIGIN = 5;
  public static final int L_MARIGIN = 5;

  /**
   * Crerates new LineNumberComponent.
   */
  public LineNumberComponent() {
    super();
  }

  @Override
  protected void paintComponent(Graphics g) {
    g.setColor(getBackground());
    Rectangle clip = g.getClipBounds();
    g.fillRect(clip.x, clip.y, clip.width, clip.height);
    g.setColor(getForeground());
    g.setFont(pane.getFont());
    int lh = getLineHeight();
    int end = clip.y + clip.height + lh;
    int lineCount = getLineNumber(pane);
    int lineNum = clip.y / lh + 1;
    // round the start to a multiple of lh, and shift by 2 pixels to align
    // properly to the text.
    for (int y = (clip.y / lh) * lh + lh - 2; y <= end && lineNum <=
lineCount; y += lh) {
      String text = String.format(format, lineNum);
      lineNum++;
      g.drawString(text, L_MARIGIN, y + getPositionCorrector());
    }
  }

  /**
   * Upddate the size of the line numbers based on the length of the document
   */
  protected void updateSize() {
    int lineCount = getLineNumber(pane);
    int h = lineCount * getLineHeight() + pane.getHeight();
    int d = (int) Math.log10(lineCount) + 2;
    if (d < 0) {
      d = 2;
    }
    int w = d * getCharWidth() + R_MARIGIN + L_MARIGIN;
    format = "%" + d + "d";
    setPreferredSize(new Dimension(w, h));
  }

  protected int getLineHeight() {
    return pane.getFontMetrics(pane.getFont()).getHeight();
  }

  protected int getCharWidth() {
    return pane.getFontMetrics(pane.getFont()).charWidth('0');
  }

  /**
   * Get the JScrollPane that contains this EditorPane, or null if no
   * JScrollPane is the parent of this editor
   * @param editorPane editor whose scroll pane must be found.
   * @return the scroll pane for the component.
   */
  public JScrollPane getScrollPane(JTextComponent editorPane) {
    JScrollPane result = null;
    if (null != editorPane.getParent() && 
        editorPane.getParent().getParent() instanceof JScrollPane) {
      result = (JScrollPane) editorPane.getParent().getParent();
    }
    return result;
  }

  @Override
  public void caretUpdate(CaretEvent e) {
    updateSize();
    revalidate();
    repaint();
  }

  public void install(JTextComponent editor) {
    this.pane = editor;
    JScrollPane sp = getScrollPane(pane);
    if (sp != null) {
      sp.setRowHeaderView(this);
      this.pane.addCaretListener(this);
      updateSize();
    }
  }

  /**
   * Installs this widget for the given text component.
   * @param editor text component whose lines must be painted.
   */
  public void deinstall(JTextComponent editor) {
    JScrollPane sp = getScrollPane(editor);
    if (sp != null) {
      editor.removeCaretListener(this);
      sp.setRowHeaderView(null);
    }
  }

  /**
   * Gets the number of lines in the given text component. Simply counts
the number of \n. 
   * This method works only for a plain document without line wrapping.
   * @param aComponent text component whose line number is to return.
   * @return number of lines in the given text component.
   */
  public static int getLineNumber(JTextComponent aComponent) {
    String text = aComponent.getText();
    int len = text.length();
    int result = 1;
    for (int i = 0; i < len; i++) {
      result += text.charAt(i) == '\n'? 1 : 0;
    }
    return result;
  }

  /**
   * Gets the value which will be incremented to the y position of line
number text. 
   * Used for better support of custom L&F.
   * @return the value which will be incremented to the y position of line
number text. 
   */
  public int getPositionCorrector() {
    return positionCorrector;
  }

  /**
   * Sets the value which will be incremented to the y position of line
number text. 
   * Used for better support of custom L&F.
   * @param aPositionCorrector increment for position of line number text.
May be 0 or negative. 
   */
  public void setPositionCorrector(int aPositionCorrector) {
    positionCorrector = aPositionCorrector;
  }

}

Original issue reported on code.google.com by ser...@mail.ru on 20 Nov 2008 at 8:24

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for the code.  However the lines going all the way to the end was 
actually
intentional.  I personally prefer it that way.  But I'll add an option to 
switch to
either flavor.
I'll also add an option to set the background color and others configurations.

Original comment by ayman.al...@gmail.com on 20 Nov 2008 at 12:22

GoogleCodeExporter commented 9 years ago
I committed version 55 with the suggested changes.  It actually does look 
better by
having line numbers for actual document lines.  And other editors I use do that 
also.

Original comment by ayman.al...@gmail.com on 20 Nov 2008 at 1:57

GoogleCodeExporter commented 9 years ago
I still cannot use the LineNumbersRuler. Please add positionCorrector from my
suggestion for vertical shift of line numbers. In my L&F the line numbers are 
about 1
px lower than text in the pane.

Original comment by ser...@mail.ru on 16 Jan 2009 at 8:59

Attachments:

GoogleCodeExporter commented 9 years ago
Will be adding the positionCorrector (possibly renamed).

Original comment by ayman.al...@gmail.com on 18 Jan 2009 at 5:11

GoogleCodeExporter commented 9 years ago
Thanks!

Original comment by ser...@mail.ru on 20 Jan 2009 at 1:06

GoogleCodeExporter commented 9 years ago
A fix is committed to r095 branch in r73.

Original comment by ayman.al...@gmail.com on 25 Jan 2009 at 1:02