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?

Improve company productivity with a Business Account.Sign Up

x
 
InteractiveMindConnect With a Mentor Commented:
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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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.