0
votes

I have a method which decides what font size to use for drawing a string. Font size depends on string length and height, and I use do-while loop to decrease font size until the string fits targetHeight. So in general it looks something like this:

private void decideOnFontSize(String text) {
    int fontSize = 72;
    do {
        font = new Font("Arial", Font.PLAIN, fontSize);
        // Calculating things...
        fontSize -= 2;
    } while (textHeight >= targetHeight);
}

With this approach I need to instantiate a new Font object every time when I need a smaller font size. Method decideOnFontSize is a part of a service in a public API, so it could be called pretty often. At first sight, instantiating new Font looks pretty wasteful in this case.

Another approach is to create a pre-defined collection of Fonts and get them as required. So I could create a utility class like this:

public class FontsUtil {

    private static Map<Integer, Font> fonts = new HashMap<>();

    public static final Integer MAX_FONT_SIZE = 72;
    public static final Integer MIN_FONT_SIZE = 10;

    static {

        String fontName = "Arial";

        for(int fontSize = MAX_FONT_SIZE; fontSize >= MIN_FONT_SIZE; fontSize -= 2) {
            fonts.put(fontSize, new Font(fontName, Font.PLAIN, fontSize));
        }
    }

    public static Font getFontBySize(Integer fontSize) {
        return fonts.get(fontSize);
    }
}

...and then I could get these pre-defined Fonts in do-while loop, so my method will look like this:

private void decideOnFontSize(String text) {
    int fontSize = FontsUtil.MAX_FONT_SIZE;
    do {
        font = FontsUtil.getFontBySize(fontSize);
        // Calculating things...
        fontSize -= 2;
    } while (textHeight >= targetHeight);
}

To my mind, the second approach looks better, because (in theory) it consumes less resources. Am I right, or it doesn't really matter?