Drawing multiline text inside a rectangle

Hi,

Can anyone point out how to draw a really long string into a rectangle such that it auto breaks on words and wraps around? I have a rectangle I want to dump the text into, so I need something like:

public void DrawIntoRect(String str, Rectangle rc)
{
     // Let the string wrap when necessary, breaking between words, using the current font.
     // If there isn't enough space, finish off with a word ellipsis?
     drawString(str, rc);
}

In win32 there are some flags you can use to do this, what is there that we can use in java?
DJ_AM_JuiceboxAsked:
Who is Participating?
 
InteractiveMindCommented:
Certainly, if using an existing text component is a viable solution, then use that.
It's just that I've had cases in the past where I've had to do this, but could not use a text component (it was for a game engine).

So, I've corrected the above code, and have posted it below. This is for the benefit of others who may have the same requirements (but cannot use a text component).

(No points for me)
Font F=...;
FontMetrics FM=getFontMetrics(F);
 
public void DrawIntoRect(String str, Rectangle rc, Graphics g)
{
   g.setFont(F);
   int lineSep=3;
   int strWidth=FM.stringWidth(str);
   int strHeight=FM.getHeight();
   int strLength=str.length();
   int charPerLine=(int)(strLength*rc.width/(double)strWidth);
   if(charPerLine>=strLength)
      g.drawString(str,rc.x,rc.y+strHeight);
   else
   {
      int lines=strLength/charPerLine;
      int skip=0;
      for(int i=1; i<=lines; i++)
      {
         String sTemp=str.substring(skip,skip+charPerLine-1);
         if(!str.substring(skip+charPerLine-1,skip+charPerLine).equals(" ")&& !str.substring(skip+charPerLine-2,skip+charPerLine-1).equals(" "))
         {
            sTemp+="-";
         }
         g.drawString(sTemp.trim(),rc.x,rc.y+i*strHeight+(i-1)*lineSep);
         skip+=charPerLine-1;
      }
      g.drawString(str.substring(skip,strLength).trim(),rc.x,rc.y+(lines+1)*strHeight+(lines)*lineSep);
   }
}

Open in new window

0
 
objectsCommented:
use a text area instead of painting it yourself.
If you're doing the painting yourself then you'll have to break the lines manually.
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
InteractiveMindCommented:
As far as I know, there is no pre-existing method which does this for you.
Below I've written up an attempt at a custom method to do the job; I haven't tested it (am off to bed in a minute), but I think at least the idea is there.

(If it doesn't work, and the problem hasn't been resolved by the morning (GMT), then I'll test it out)
Font F=...;
FontMetrics FM=getFontMetrics(F);
 
public void DrawIntoRect(String str, Rectangle rc, Graphics g)
{
   g.setFont(F);
   int lineSep=3;
   int strWidth=FM.stringWidth(str);
   int strHeight=FM.getHeight();
   int strLength=str.length();
   int charPerLine=(int)(strLength*rc.width/(double)strWidth);
   if(charPerLine>=strLength)
      g.drawString(str,rc.x,rc.y+strHeight);
   else
   {
      int lines=strLength/charPerLine;
      int skip=0;
      for(int i=1; i<=lines; i++)
      {
         String sTemp=str.substring(skip,skip+charPerLine-1);
         if(!str.substring(skip+charPerLine-1,skip+charPerLine).equals(" ")&& !str.substring(skip+charPerLine-2,skip+charPerLine-1).equals(" "))
         {
            sTemp+="-";
         }
         g.drawString(sTemp,rc.x,rc.y+i*strHeight+(i-1)*lineSep);
         skip+=charPerLine;
      }
      g.drawString(str.substring(skip,strLength),rc.y+lines*strHeight+(lines-1)*lineSep);
   }
}

Open in new window

0
 
objectsCommented:
functionality is already avail in text components :)
0
 
DJ_AM_JuiceboxAuthor Commented:
@objects:
But can you change the color of the background of the text component, and modify the font? I could use it if it 'appeared' as if it were painted by me.

@InteractiveMind:
I had to do the same thing in C++  a while back, this should me,

Thanks
0
 
objectsCommented:
> But can you change the color of the background of the text component, and modify the font?

absolutely, you can even apply whatever styles you want by using a JTextPane.
0
 
DJ_AM_JuiceboxAuthor Commented:
@InteractiveMind:
It seems to work, thanks!

@objects:
Same question as in other html post - if I use the text area object, can I just stick it above the device context of my applet? I mean the whole applet dimensions are part of my drawing context, so if I just stick this panel on top of a portion of it, what effect will it have? Will it start flickering everytime I repaint?

Thanks
0
 
objectsCommented:
you can place it whereeve you want in your component hierarchy.
it shouldn't flicker.
0
 
InteractiveMindCommented:
(So long as you're using Swing, then it shouldn't flicker - as it has double-buffering built in, from what I remember)
0
 
DJ_AM_JuiceboxAuthor Commented:
In all the examples I find about text panels, the main class looks like:

    public class TextDemo extends JPanel implements ActionListener

but I don't derive from JPanel, I derive from:

    java.applet.Applet implements Runnable

Can I still use the text panel?
0
 
objectsCommented:
yes, you can use whatever components you want. They are all derived from Component.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.