Keep track of line number next to JTextArea

I'm working on a simple java IDE for personal use, but I'm having trouble when it comes to displaying line numbes for the file you're editing.

Here's how the IDE I currently use displays line numbers:
http://gaming.cyntaks.com/lines.gif

And here's a screen of the IDE i'm writing:
http://gaming.cyntaks.com/RDE.gif

I can't seem to figure out how I'm going to go about displaying the line numbers next to my JTextArea.  When I was designing my IDE, the plan was to subclass a JPanel, and simply draw the line numbers in the area to the left of the textarea displaying, and then offset the y when you scroll the textarea.  However, I am worried that my line numbers will get offset, because I don't think that the row height in JTextArea's are consistant across operating systems.

One other option that I considered was to use another JTextArea to display the line numbers.  That way, the rows for both of the JTextArea's will line up. When I scroll the textarea containing the code, the textarea containing the line numbers would scroll accordingly.  However, I don't want to see a scrollbar next to the line numbers.  If I set the scrollbar's visibility to false, will the textarea still reserve room for it, and can I still scroll the textarea up and down?

Thanks
LVL 2
BreadstickAsked:
Who is Participating?
 
ee_ai_constructConnect With a Mentor Commented:
Closed, 95 points refunded.
modname
Community Support Moderator
0
 
armoghanCommented:
Use JEditorPane instead
this link may help
http://www.developer.com/java/other/article.php/3318421
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
BreadstickAuthor Commented:
Thanks, I got it working, but I'm still having a problem.

Everything's working well, except long lines of text are wrapping, and it's counting the wrapped text as another line... Here's a screenshot of what I mean:
http://gaming.cyntaks.com/RDE_2.gif

And here's some of my code:

[code]
 class NumberedEditorKit extends StyledEditorKit
  {
      public ViewFactory getViewFactory()
      {
          return new NumberedViewFactory();
      }
  }

  class NumberedViewFactory implements ViewFactory
  {
      public View create(Element elem)
      {
          String kind = elem.getName();
          if (kind != null)
              if (kind.equals(AbstractDocument.ContentElementName))
              {
                  return new LabelView(elem);
              }
              else if (kind.equals(AbstractDocument.ParagraphElementName))
              {
  //              return new ParagraphView(elem);
                  return new NumberedParagraphView(elem);
              }
              else if (kind.equals(AbstractDocument.SectionElementName))
              {
                  return new BoxView(elem, View.Y_AXIS);
              }
              else if (kind.equals(StyleConstants.ComponentElementName))
              {
                  return new ComponentView(elem);
              }
              else if (kind.equals(StyleConstants.IconElementName))
              {
                  return new IconView(elem);
              }
          // default to text display
          return new LabelView(elem);
      }
  }

  class NumberedParagraphView extends ParagraphView
  {
    public short NUMBERS_WIDTH=30;
 
    public NumberedParagraphView(Element e)
    {
        super(e);
        short top = 0;
        short left = 0;
        short bottom = 0;
        short right = 0;
        this.setInsets(top, left, bottom, right);
    }
 
    protected void setInsets(short top, short left, short bottom,short right)
    {
      super.setInsets(top, (short)(left+NUMBERS_WIDTH), bottom, right);
    }
 
    public void paintChild(Graphics g, Rectangle r, int n)
    {
        super.paintChild(g, r, n);
        Graphics2D g2 = (Graphics2D)g;
        int previousLineCount = getPreviousLineCount();
        int numberX = r.x - getLeftInset();
        int numberY = r.y + r.height - 5;
        String str = Integer.toString(previousLineCount + n + 1);
        // draw the line number, align it to the right
        g2.drawString(str, numberX - g2.getFontMetrics().stringWidth(str) + 25, numberY);
        g2.setColor(Color.lightGray);
        //draw a vertical line next to it
        g2.drawLine(r.x-3, r.y, r.x-3, r.y + r.height);
    }
 
    public int getPreviousLineCount()
    {
        int lineCount = 0;
        View parent = this.getParent();
        int count = parent.getViewCount();
        for (int i = 0; i < count; i++)
        {
            if (parent.getView(i) == this)
            {
                break;
            }
            else
            {
                lineCount += parent.getView(i).getViewCount();
            }
        }
        return lineCount;
    }
  }
...
        JEditorPane fileText = new JEditorPane();
        fileText.setEditorKit(new NumberedEditorKit());
        JScrollPane fileContainer = new JScrollPane(fileText,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
...

[/code]

The JEditorPane is in a JScrollPane, but it's not using the horizontal scrollbar, even though i've explicitly turned it on.

I need to either get the text to not wrap, or I need lines that are a continuation of one long line to not be counted when displaying the line count.

Any ideas?
0
 
expertmbCommented:
public NumberedParagraphView(Element e) {
        super(e);
        short top = 0;
        short left = 0;
        short bottom = 0;
        short right = 0;//+1000;
        this.setInsets(top, left, bottom, right);
    }

0
 
BreadstickAuthor Commented:
Thanks, but that doesn't help me.  I ended up using a different approach involving the JScrollPane's row header.
0
 
expertmbCommented:
>>I ended up using a different approach involving the JScrollPane's row header.
please post the code, curious to know how it solved your problem.

mb...
0
 
BreadstickAuthor Commented:
   fileContainer.setRowHeaderView(new LineNumberView(fileText));

Where fileContainer is the JScrollPane I'm using, fileText is my JTextPane, and LineNumberView is a component written by somebody named "uncle_alice" that paints the line numbers.  I found help at:
http://forum.java.sun.com/thread.jsp?forum=57&thread=555641&tstart=15&trange=15
0
 
expertmbCommented:
0
 
BreadstickAuthor Commented:
>> plz post the working complete code. as i posted

Here's the thread with the complete working LineNumberView code I'm using for the row header in my JScrollPane:
http://forum.java.sun.com/thread.jsp?forum=57&thread=547941

This is where I use the LineNumberView:
theScrollPaneMyTextComponentIsIn.setRowHeaderView(new LineNumberView(myTextComponent));

Here's the thread where I originally asked the question and was walked through getting it to work:
http://forum.java.sun.com/thread.jsp?forum=57&thread=555641

Here's a screenshot of it working:
http://gaming.cyntaks.com/RDE3.gif

Thanks for your help, but I solved my problem using a completely different approach, which was more convenient for what I was trying to accomplish.
0
All Courses

From novice to tech pro — start learning today.