5

Running the following code:

import java.awt.Font;
import java.awt.FontMetrics;

public class MetricsTest {

    public static void main(String[] args) {
                Font myFontTest=new Font("Arial", Font.PLAIN, 11);
                FontMetrics metrics  = new FontMetrics(myFontTest) {};
                int characterWidth=metrics.charWidth('A');
                System.out.println(characterWidth);
    }
}

produces this error:

Exception in thread "main" java.lang.StackOverflowError

at java.awt.FontMetrics.getWidths(FontMetrics.java:430)

at java.awt.FontMetrics.charWidth(FontMetrics.java:333)

at java.awt.FontMetrics.getWidths(FontMetrics.java:430)

at java.awt.FontMetrics.charWidth(FontMetrics.java:333)

at java.awt.FontMetrics.getWidths(FontMetrics.java:430)

and so on....

Why?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
geo
  • 517
  • 1
  • 9
  • 28
  • 1
    You cannot just create a `new FontMetrics` you need to get one from _somewhere_. You are not running in the EDT and have no Swing components - the font is not being rendered so how can it have a width? – Boris the Spider Mar 04 '14 at 16:51

3 Answers3

3

From the doc:

Note to subclassers: Since many of these methods form closed, mutually recursive loops, you must take care that you implement at least one of the methods in each such loop to prevent infinite recursion when your subclass is used. In particular, the following is the minimal suggested set of methods to override in order to ensure correctness and prevent infinite recursion (though other subsets are equally feasible):

This:

FontMetrics metrics  = new FontMetrics(myFontTest) {};

defines a subclass without any methods overridden, hence the behaviour you're seeing.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
2

Here is a solution:
(see comment by user Boris the Spider) on my original post)

import java.awt.Canvas;
import java.awt.Font;
import java.awt.FontMetrics;

public class MetricsTest {

    public static void main(String[] args) {
                Font myFontTest=new Font("Arial", Font.PLAIN, 11);
                Canvas c = new Canvas();
                FontMetrics fm = c.getFontMetrics(myFontTest);
                int characterWidth=fm.charWidth('A');
                System.out.println(characterWidth);

    }

}
geo
  • 517
  • 1
  • 9
  • 28
1

Rewrite your code as follows :

try {
    Font myFontTest=new Font("Arial", Font.PLAIN, 11);
    Frame f = new Frame();
    //FontMetrics metrics = f.getToolkit().getFontMetrics(myFontTest);      
    FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(myFontTest);

    int characterWidth=metrics.charWidth('A');
    System.out.println(characterWidth);
} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Visruth
  • 3,430
  • 35
  • 48
  • Is using a Frame better that using a canvas? (see my own answer) – geo Mar 04 '14 at 17:13
  • as per documentatioin `getToolkit().getFontMetrics(myFontTest)` is a deprecated method. But, I think it will be better if you use if it is available. refer the documentation of canvas.getFontMetrics method. – Visruth Mar 04 '14 at 17:27