special character problem

I found out that the drawString method cannot paint special characters like \n, \t and so on.

What can i do to overcome this? ???

tokenize the string, calc. character height, do multiple drawString()?

Have you found a nice way to compute the size of a string? I tried to once, it was nasty. You have to walk a long road - font, font metrics, etc. Has anyone found a nice way to do that?


public static Dimension getStringLength(String str, Font font){
   FontMetrics metrics = /*your game frame*/.getFontMetrics(font);            
   Dimension textSize = new Dimension();
   textSize.width = metrics.stringWidth(str) + 2 * metrics.charWidth(' ');
    textSize.height += metrics.getAscent() + metrics.getDescent() + 1;
    return textSize;
}
......
Dim d = getStringLength("Hello world", new Font("Times new roman", FONT.BOLD, 24);
System.out.println("string width in pixels: " + d.width);
System.out.println("string height in pixels: " + d.height);

And below a small help class to wrap a string to a specified width.


package org.backmask.util.font;

import java.awt.Font;
import java.awt.FontMetrics;
import java.util.StringTokenizer;
import java.util.Vector;

public class FontWrapManager {

      private String[] data = null;
      private StringTokenizer tok = null;
      private int lineNum = 0;

      public FontWrapManager(String[] text) {
            this.data = text;
            this.lineNum = 0;
            this.tok = new StringTokenizer(this.data[lineNum], " \t\n\r", true);
      }

      public FontWrapManager(String text) {
            this.data = new String[1];
            this.data[0] = text;
            this.lineNum = 0;
            this.tok = new StringTokenizer(this.data[lineNum], " \t\n\r", true);
      }

      public String[] wrapForWidth(int width, FontMetrics metrics) {
            Vector lines = new Vector();

            String word = "";
            String line = "";
            while (true){
                  word = nextToken();
                  
                  //end of data array
                  if (word == null){
                        System.out.println("word = null: adding line: " + line);
                        lines.add(line);
                        break;
                  }
                        
                  if (word.equals("\n")) {
                        lines.add(line);
                        line = "";
                  }
      
                  if (metrics.stringWidth(line + " " + word) > (width - 2)){
                        lines.add(line);
                        line = word;
                  } else {
                        line = line + " " + word;
                  }
            }

          String[] newData = new String[lines.size()];
          for (int i=0; i<lines.size(); i++)
                  newData[i] = (String) lines.elementAt(i);

          return newData;
      }

      /**
       * This method is used to tokenize the text in the array.  It lets
       * us treat the data in the array as a Stream.
       *
       * @return The next token of data.  This includes whitespace, so the
       *         caller can look for repeated newlines.
       */
      private String nextToken(){

            while (!this.tok.hasMoreTokens()) {
                  if (lineNum == (this.data.length - 1))
                        return null;
                  this.tok =      new StringTokenizer(this.data[++lineNum], " \t\n\r", true);
            }

            return tok.nextToken();

      }

}
.....................................
//wrap the story text
FontWrapManager fw = new FontWrapManager("This is a very long text line that need to be wrap due to the rectangle where the text should be painted on has only a width of 40px");
String[] wrap = fw.wrapForWidth(40, frame.getFontMetrics(font));

for (int i=0; i<wrap.length; i++)
   g.drawString(wrap[i], x, y + font_height + (font_height + 1)*i);


Hope it helps.