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?
The most common case that can possibly exhaust a Java application’s stack is recursion. In recursion, a method invokes itself during its execution. Recursion is considered as a powerful general-purpose programming technique, but it must be used with caution, to avoid StackOverflowError. An example of throwing a StackOverflowError is shown below:
The values returned by these methods are in font design units, so they are independent of the size and units of a particular Font object. The following example displays the metrics for the regular style of the Arial font family.
It should be pointed out that it's almost impossible to "handle" a stack overflow error. In most environments, to handle the error one needs to run code on the stack, which is difficult if there is no more stack space. @JB King: Doesn't really apply to Java, where only primitive types and references are kept on the stack.
Some of the most common causes for a java.lang.StackOverflowError are: Deep or infinite recursion - If a method calls itself recursively without a terminating condition. Cyclic relationships between classes - If a class A instantiates an object of class B, which in turn instantiates an object of class A.
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With