Load New Fonts at Runtime #61
Chapter 8, Rendering
These are all JComponents, but they’re notably lacking the “J”
that starts the name of typical Swing components (
for JTree, TextArea.font for JTextArea, etc.).
Now that you know the keys for the UIDefaults table, instead of blindly
changing all of them to the same font, you can customize a look by applying
different fonts—or different sizes and styles of one or two base fonts—to
H A C K
Load New Fonts at Runtime Hack #61
Who cares what fonts your users have? Bundle the fonts you want your
application to use and load those fonts dynamically!
Using fonts with any predictability used to be a nightmare in Java. For a
while, you could only depend on having access to one serif, one sans-serif,
and one monospaced font, and the constants you’d use to get those fonts
changed between Java 1.0 and 1.1. Fortunately, you’re now free to use any
font installed on the user’s machine and load it by name.
Of course, not everyone has the same fonts. Even different installations of
the same operating system will have different fonts available. I still use some
TrueType fonts I’ve been toting from machine to machine for 15 years, and
it’s a safe bet that very few other people will have those same fonts.
This would seem to limit your Swing application to using only the fonts you
know are installed with an operating system—maybe Arial and Times New
Roman on Windows, Lucida Grande and Palatino on Mac OS X, etc. But it’s
not so. You can load font files at runtime and make them available to your
Java application, even if the font isn’t installed on the user’s machine.
The Wonders of createFont( )
Using dynamically loaded fonts comes down to a single, critical, often over-
looked AWT method in the
Font class: createFont( ). This method, intro-
duced in Java 1.3, takes two parameters: a font format (as an
int), which to
date has no legal value other than
Font.TRUETYPE_FONT, and an InputStream.
This stream is typically a
FileInputStream from a .ttf TrueType file, or some
equivalent. By equivalent, I meant that you could presumably put the font
on the network and get a stream from a
URL or put the font file inside a .jar,
find it along the classpath with
ClassLoader.getResourceAsStream( ), and
load from that.