Solved

Keep track of line number next to JTextArea

Posted on 2004-09-16
12
335 Views
Last Modified: 2012-06-27
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
0
Comment
Question by:Breadstick
  • 4
  • 3
  • 2
  • +1
12 Comments
 
LVL 18

Expert Comment

by:armoghan
ID: 12081943
Use JEditorPane instead
this link may help
http://www.developer.com/java/other/article.php/3318421
0
 
LVL 18

Expert Comment

by:armoghan
ID: 12081946
0
 
LVL 2

Author Comment

by:Breadstick
ID: 12089360
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:expertmb
ID: 12102563
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
 
LVL 2

Author Comment

by:Breadstick
ID: 12105762
Thanks, but that doesn't help me.  I ended up using a different approach involving the JScrollPane's row header.
0
 
LVL 6

Expert Comment

by:expertmb
ID: 12108789
>>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
 
LVL 2

Author Comment

by:Breadstick
ID: 12109911
   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
 
LVL 6

Expert Comment

by:expertmb
ID: 12109956
0
 
LVL 2

Author Comment

by:Breadstick
ID: 12153199
>> 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
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
ID: 12154912
Closed, 95 points refunded.
modname
Community Support Moderator
0

Featured Post

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
login jsp example 24 87
how to install java on RHEL image on EC2 4 58
Detect Closed Loops (circles, figure-8s, etc) in PNG Images 6 78
Eclipse for Java EE development 2 45
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question