This code snippet creates an image which contains text. I set the font to Serif. However, when I query the resulting image later on for its font face, it returns Dialog. I don't understand why this is.
BufferedImage img = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(img, 0, 0, 200, 100, this); // "this" refers to my custom JPanel which I am setting in the JFrame.
g2d.setPaint(Color.red);
g2d.setFont(new Font("Serif", Font.BOLD, 20));
System.out.println("from g2d object: " + g2d.getFont().getFamily()); // outputs "Serif"
String s = "Hello, world!";
FontMetrics fm = g2d.getFontMetrics();
int x = img.getWidth() - fm.stringWidth(s) - 5;
int y = fm.getHeight();
g2d.drawString(s, x, y);
g2d.dispose();
System.out.println("from image: " + img.getGraphics().getFont().getFamily()); // outputs "Dialog" (expected "Serif")
I understand that Dialog is one of the logical fonts in Java, but if the font is set to be something else, and Font.getFontName()
returns the font face for the given font, why isn't it returning Serif as set in the Graphics2D
object?
UPDATE: Calling g2d.dispose()
before or after the last System.out.println()
makes no difference. Both ways, it still prints out Dialog.
TL:DR The font is not accessible in Graphics
or Graphics2D
.
Whether you invoke BufferedImage#createGraphics()
directly or BufferedImage#getGraphics()
the end result is the same: they both create a new graphics object. More specifically, the former returns a new Graphics
object and the latter returns a Graphics2D
object. Both are abstractions of the concrete type returned which is an instance of SunGraphics2D
. Unfortunately, this object does not store any information set, related to the font, in the graphics object. So basically, I cannot get the data I need from the image object.
In contrast, ProxyGraphics2D
and PeekGraphics
- both subtypes of the abstract class Graphics2D
class do store such information in a Graphics2D
global variable called mGraphics
. This object is accessed via the getDelegate()
method, which is obviously not part of the Graphics
or Graphics2D
API. Unfortunately, both of these subclasses are part of the sun
package which is no longer accessible. Examining these classes clearly shows that methods like setFont()
do save the font in this delegate (Graphics2D
) object.