epubjs
Version:
Render ePub documents in the browser, across many devices
206 lines (191 loc) • 33.5 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Using Fonts</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Using Fonts"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-20-SECT-6"/>Using Fonts</h1></div></div></div><p><a id="idx11087" class="indexterm"/> <a id="idx11097" class="indexterm"/>Text fonts in Java are represented by instances of the
<a id="I_indexterm20_id812194" class="indexterm"/><code class="literal">java.awt.Font</code> class. A
<code class="literal">Font</code> object is constructed from a name,
style identifier, and a point size. We can create a <code class="literal">Font</code> object at any time, but it’s meaningful
only when applied to a particular component on a given display device.
Here are a couple of fonts:</p><a id="I_20_tt1153"/><pre class="programlisting"> <code class="n">Font</code> <code class="n">smallFont</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Font</code><code class="o">(</code><code class="s">"Monospaced"</code><code class="o">,</code> <code class="n">Font</code><code class="o">.</code><code class="na">PLAIN</code><code class="o">,</code> <code class="mi">10</code><code class="o">);</code>
<code class="n">Font</code> <code class="n">bigFont</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Font</code><code class="o">(</code><code class="s">"Serif"</code><code class="o">,</code> <code class="n">Font</code><code class="o">.</code><code class="na">BOLD</code><code class="o">,</code> <code class="mi">18</code><code class="o">);</code></pre><p>Font names come in three varieties: <a id="I_indexterm20_id812230" class="indexterm"/><span class="emphasis"><em>family</em></span> names, <span class="emphasis"><em>face</em></span>
names (also called font names), and <a id="I_indexterm20_id812243" class="indexterm"/><span class="emphasis"><em>logical</em></span> names. Family and font names
are closely related. For example, Garamond Italic is a font name for a
font whose family name is Garamond.</p><p>A <span class="emphasis"><em>logical name</em></span> is a generic name for the font
family. The following logical font names should be available on all
platforms:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p><a id="I_indexterm20_id812262" class="indexterm"/> <code class="literal">Serif</code> (generic name
for <code class="literal">TimesRoman</code>)</p></li><li class="listitem"><p><a id="I_indexterm20_id812282" class="indexterm"/> <code class="literal">SansSerif</code> (generic
name for <code class="literal">Helvetica</code>)</p></li><li class="listitem"><p><a id="I_indexterm20_id812301" class="indexterm"/> <code class="literal">Monospaced</code> (generic
name for <code class="literal">Courier</code>)</p></li><li class="listitem"><p><a id="I_indexterm20_id812321" class="indexterm"/> <code class="literal">Dialog</code></p></li><li class="listitem"><p><a id="I_indexterm20_id812334" class="indexterm"/> <code class="literal">DialogInput</code></p></li></ul></div><p>The logical font name is mapped to an actual font on the local
platform. Java’s <span class="emphasis"><em>fonts.properties</em></span> file maps the font
names to the available fonts, covering as much of the Unicode character
set as possible. If you request a font that doesn’t exist, you get the
default font.</p><p>One of the big wins in the 2D API is that it can use most of the
fonts you have installed on your computer. The following program prints
out a full list of the fonts that are available to the 2D API:</p><a id="I_20_tt1154"/><pre class="programlisting"> <code class="c1">//file: ShowFonts.java</code>
<code class="kn">import</code> <code class="nn">java.awt.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">ShowFonts</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code><code class="n">String</code><code class="o">[]</code> <code class="n">args</code><code class="o">)</code> <code class="o">{</code>
<code class="n">Font</code><code class="o">[]</code> <code class="n">fonts</code><code class="o">;</code>
<code class="n">fonts</code> <code class="o">=</code>
<code class="n">GraphicsEnvironment</code><code class="o">.</code><code class="na">getLocalGraphicsEnvironment</code><code class="o">().</code><code class="na">getAllFonts</code><code class="o">();</code>
<code class="k">for</code> <code class="o">(</code><code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code> <code class="n">i</code> <code class="o"><</code> <code class="n">fonts</code><code class="o">.</code><code class="na">length</code><code class="o">;</code> <code class="n">i</code><code class="o">++)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">print</code><code class="o">(</code><code class="n">fonts</code><code class="o">[</code><code class="n">i</code><code class="o">].</code><code class="na">getFontName</code><code class="o">()</code> <code class="o">+</code> <code class="s">" : "</code><code class="o">);</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">print</code><code class="o">(</code><code class="n">fonts</code><code class="o">[</code><code class="n">i</code><code class="o">].</code><code class="na">getFamily</code><code class="o">()</code> <code class="o">+</code> <code class="s">" : "</code><code class="o">);</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">print</code><code class="o">(</code><code class="n">fonts</code><code class="o">[</code><code class="n">i</code><code class="o">].</code><code class="na">getName</code><code class="o">());</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">();</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Note, however, that the fonts installed on your system may not match
the fonts installed on someone else’s system. For true portability, you
can use one of the logical names (although your application won’t look
exactly the same on all platforms) or go with the defaults. Alternatively,
you can test for the existence of your preferred font and fall back on a
logical font, or you can allow your users to configure the application by
choosing fonts themselves.</p><p>The <code class="literal">static</code> method <a id="I_indexterm20_id812388" class="indexterm"/><code class="literal">Font.getFont()</code> looks up a
font by name in the system properties list just like <a id="I_indexterm20_id812399" class="indexterm"/><code class="literal">Color.getColor()</code>. And as
with <code class="literal">Color.getColor()</code>, this is
interesting but useless. Normally, you’ll either choose a <code class="literal">Font</code> from one that is available in the
environment (as in the <code class="literal">ShowFonts</code>
example) or use identifiers to describe the font you want in the <code class="literal">Font</code> constructor.</p><p>The <code class="literal">Font</code> class defines three
<code class="literal">static</code> style identifiers: <a id="I_indexterm20_id812447" class="indexterm"/><code class="literal">PLAIN</code>, <a id="I_indexterm20_id812458" class="indexterm"/><code class="literal">BOLD</code>, and <a id="I_indexterm20_id812468" class="indexterm"/><code class="literal">ITALIC</code>. You can use these
values on all fonts, although some fonts may not provide bold or italic
versions. The point size determines the size of the font on a display. If
a given point size isn’t available, <code class="literal">Font</code> substitutes a default size.</p><p>You can retrieve information about an existing <code class="literal">Font</code> with a number of routines. The <a id="I_indexterm20_id812497" class="indexterm"/><code class="literal">getName()</code>, <a id="I_indexterm20_id812507" class="indexterm"/><code class="literal">getSize()</code>, and <a id="I_indexterm20_id812518" class="indexterm"/><code class="literal">getStyle()</code> methods
retrieve the logical name, point size, and style, respectively. You can
use the <a id="I_indexterm20_id812530" class="indexterm"/><code class="literal">getFamily()</code> method to
find out the family name, while <a id="I_indexterm20_id812541" class="indexterm"/><code class="literal">getFontName()</code> returns the
face name of the font.</p><p>Finally, to actually use a <code class="literal">Font</code>
object, you can simply specify it as an argument to the <a id="I_indexterm20_id812560" class="indexterm"/><code class="literal">setFont()</code> method of a
<code class="literal">Component</code> or <code class="literal">Graphics2D</code> object. Subsequent text drawing
commands such as <code class="literal">drawString()</code> for that
component or in that graphics context use the specified font.</p><div class="sect2" title="Font Metrics"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-20-SECT-6.1"/>Font Metrics</h2></div></div></div><p>To get detailed size and spacing information for text rendered in
a font, we can ask for a <a id="I_indexterm20_id812597" class="indexterm"/><code class="literal">java.awt.font.LineMetrics</code> object. Different
systems have different real fonts available; the available fonts may not
match the font you request. Furthermore, the measurements of different
characters within a single font may be different, especially in
multilingual text. Thus, a <code class="literal">LineMetrics</code> object presents information about
a particular set of text in a particular font on a particular system,
not general information about a font. For example, if you ask for the
metrics of a nine-point <code class="literal">Monospaced</code>
font, what you get isn’t some abstract truth about <code class="literal">Monospaced</code> fonts; you get the metrics of the
font that the particular system uses for nine-point <code class="literal">Monospaced</code>—which may not be exactly nine
points or even fixed width.</p><p>Use the <a id="I_indexterm20_id812638" class="indexterm"/><code class="literal">getLineMetrics()</code> method
for a <code class="literal">Font</code> to retrieve the metrics
for text as it would appear for that component. This method also needs
to know some information about how you plan to render the text—if you’re
planning to use anti-aliasing, for instance, which affects the text
measurements. This extra information is encapsulated in the <a id="I_indexterm20_id812660" class="indexterm"/><code class="literal">FontRenderContext</code>
class. Fortunately, you can just ask <code class="literal">Graphics2D</code> for its current <code class="literal">FontRenderContext</code> rather than having to create
one yourself:</p><a id="I_20_tt1155"/><pre class="programlisting"> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">paint</code><code class="o">(</code><code class="n">Graphics</code> <code class="n">g</code><code class="o">)</code> <code class="o">{</code>
<code class="n">Graphics2D</code> <code class="n">g2</code> <code class="o">=</code> <code class="o">(</code><code class="n">Graphics2D</code><code class="o">)</code><code class="n">g</code><code class="o">;</code>
<code class="o">...</code>
<code class="n">FontRenderContext</code> <code class="n">frc</code> <code class="o">=</code> <code class="n">g2</code><code class="o">.</code><code class="na">getFontRenderContext</code><code class="o">();</code>
<code class="n">LineMetrics</code> <code class="n">metrics</code> <code class="o">=</code> <code class="n">font</code><code class="o">.</code><code class="na">getLineMetrics</code><code class="o">(</code><code class="s">"Monkey"</code><code class="o">,</code> <code class="n">frc</code><code class="o">);</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>The <code class="literal">Font</code> class also has a
<a id="I_indexterm20_id812701" class="indexterm"/><code class="literal">getStringBounds()</code>
method that returns the bounding box of a piece of text:</p><a id="I_20_tt1156"/><pre class="programlisting"> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">paint</code><code class="o">(</code><code class="n">Graphics</code> <code class="n">g</code><code class="o">)</code> <code class="o">{</code>
<code class="n">Graphics2D</code> <code class="n">g2</code> <code class="o">=</code> <code class="o">(</code><code class="n">Graphics2D</code><code class="o">)</code><code class="n">g</code><code class="o">;</code>
<code class="o">...</code>
<code class="n">FontRenderContext</code> <code class="n">frc</code> <code class="o">=</code> <code class="n">g2</code><code class="o">.</code><code class="na">getFontRenderContext</code><code class="o">();</code>
<code class="kt">float</code> <code class="n">messageWidth</code> <code class="o">=</code>
<code class="o">(</code><code class="kt">float</code><code class="o">)</code><code class="n">font</code><code class="o">.</code><code class="na">getStringBounds</code><code class="o">(</code><code class="s">"Monkey"</code><code class="o">,</code> <code class="n">frc</code><code class="o">).</code><code class="na">getWidth</code><code class="o">();</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>The following application, <code class="literal">FontShow</code>, displays a word and draws reference
lines showing certain characteristics of its font, as shown in <a class="xref" href="ch20s06.html#learnjava3-CHP-20-FIG-3" title="Figure 20-3. The FontShow application">Figure 20-3</a>. Clicking in the application window
toggles the point size between a small and a large value.</p><a id="I_20_tt1157"/><pre class="programlisting"> <code class="c1">//file: FontShow.java</code>
<code class="kn">import</code> <code class="nn">java.awt.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.awt.event.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.awt.font.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">FontShow</code> <code class="kd">extends</code> <code class="n">JComponent</code>
<code class="o">{</code>
<code class="kd">private</code> <code class="kd">static</code> <code class="kd">final</code> <code class="kt">int</code> <code class="n">PAD</code> <code class="o">=</code> <code class="mi">25</code><code class="o">;</code> <code class="c1">// frilly line padding</code>
<code class="kd">private</code> <code class="kt">boolean</code> <code class="n">bigFont</code> <code class="o">=</code> <code class="kc">true</code><code class="o">;</code>
<code class="kd">private</code> <code class="n">String</code> <code class="n">message</code><code class="o">;</code>
<code class="kd">public</code> <code class="nf">FontShow</code><code class="o">(</code><code class="n">String</code> <code class="n">message</code><code class="o">)</code> <code class="o">{</code>
<code class="k">this</code><code class="o">.</code><code class="na">message</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code>
<code class="n">addMouseListener</code><code class="o">(</code><code class="k">new</code> <code class="n">MouseAdapter</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseClicked</code><code class="o">(</code><code class="n">MouseEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">bigFont</code> <code class="o">=</code> <code class="o">!</code><code class="n">bigFont</code><code class="o">;</code>
<code class="n">repaint</code><code class="o">();</code>
<code class="o">}</code>
<code class="o">});</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">paint</code><code class="o">(</code><code class="n">Graphics</code> <code class="n">g</code><code class="o">)</code>
<code class="o">{</code>
<code class="n">Graphics2D</code> <code class="n">g2</code> <code class="o">=</code> <code class="o">(</code><code class="n">Graphics2D</code><code class="o">)</code><code class="n">g</code><code class="o">;</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setRenderingHint</code><code class="o">(</code><code class="n">RenderingHints</code><code class="o">.</code><code class="na">KEY_ANTIALIASING</code><code class="o">,</code>
<code class="n">RenderingHints</code><code class="o">.</code><code class="na">VALUE_ANTIALIAS_ON</code><code class="o">);</code>
<code class="kt">int</code> <code class="n">size</code> <code class="o">=</code> <code class="n">bigFont</code> <code class="o">?</code> <code class="mi">96</code> <code class="o">:</code> <code class="mi">64</code><code class="o">;</code>
<code class="n">Font</code> <code class="n">font</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Font</code><code class="o">(</code><code class="s">"Dialog"</code><code class="o">,</code> <code class="n">Font</code><code class="o">.</code><code class="na">PLAIN</code><code class="o">,</code> <code class="n">size</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setFont</code><code class="o">(</code><code class="n">font</code><code class="o">);</code>
<code class="kt">int</code> <code class="n">width</code> <code class="o">=</code> <code class="n">getSize</code><code class="o">().</code><code class="na">width</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">height</code> <code class="o">=</code> <code class="n">getSize</code><code class="o">().</code><code class="na">height</code><code class="o">;</code>
<code class="n">FontRenderContext</code> <code class="n">frc</code> <code class="o">=</code> <code class="n">g2</code><code class="o">.</code><code class="na">getFontRenderContext</code><code class="o">();</code>
<code class="n">LineMetrics</code> <code class="n">metrics</code> <code class="o">=</code> <code class="n">font</code><code class="o">.</code><code class="na">getLineMetrics</code><code class="o">(</code><code class="n">message</code><code class="o">,</code> <code class="n">frc</code><code class="o">);</code>
<code class="kt">float</code> <code class="n">messageWidth</code> <code class="o">=</code>
<code class="o">(</code><code class="kt">float</code><code class="o">)</code><code class="n">font</code><code class="o">.</code><code class="na">getStringBounds</code><code class="o">(</code><code class="n">message</code><code class="o">,</code> <code class="n">frc</code><code class="o">).</code><code class="na">getWidth</code><code class="o">();</code>
<code class="c1">// center text</code>
<code class="kt">float</code> <code class="n">ascent</code> <code class="o">=</code> <code class="n">metrics</code><code class="o">.</code><code class="na">getAscent</code><code class="o">();</code>
<code class="kt">float</code> <code class="n">descent</code> <code class="o">=</code> <code class="n">metrics</code><code class="o">.</code><code class="na">getDescent</code><code class="o">();</code>
<code class="kt">float</code> <code class="n">x</code> <code class="o">=</code> <code class="o">(</code><code class="n">width</code> <code class="o">-</code> <code class="n">messageWidth</code><code class="o">)</code> <code class="o">/</code> <code class="mi">2</code><code class="o">;</code>
<code class="kt">float</code> <code class="n">y</code> <code class="o">=</code> <code class="o">(</code><code class="n">height</code> <code class="o">+</code> <code class="n">metrics</code><code class="o">.</code><code class="na">getHeight</code><code class="o">())</code> <code class="o">/</code> <code class="mi">2</code> <code class="o">-</code> <code class="n">descent</code><code class="o">;</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setPaint</code><code class="o">(</code><code class="n">getBackground</code><code class="o">());</code>
<code class="n">g2</code><code class="o">.</code><code class="na">fillRect</code><code class="o">(</code><code class="mi">0</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="n">width</code><code class="o">,</code> <code class="n">height</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setPaint</code><code class="o">(</code><code class="n">getForeground</code><code class="o">());</code>
<code class="n">g2</code><code class="o">.</code><code class="na">drawString</code><code class="o">(</code><code class="n">message</code><code class="o">,</code> <code class="n">x</code><code class="o">,</code> <code class="n">y</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setPaint</code><code class="o">(</code><code class="n">Color</code><code class="o">.</code><code class="na">white</code><code class="o">);</code> <code class="c1">// Base lines</code>
<code class="n">drawLine</code><code class="o">(</code><code class="n">g2</code><code class="o">,</code> <code class="n">x</code> <code class="o">-</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code><code class="o">,</code> <code class="n">x</code> <code class="o">+</code> <code class="n">messageWidth</code> <code class="o">+</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code><code class="o">);</code>
<code class="n">drawLine</code><code class="o">(</code><code class="n">g2</code><code class="o">,</code> <code class="n">x</code><code class="o">,</code> <code class="n">y</code> <code class="o">+</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">x</code><code class="o">,</code> <code class="n">y</code> <code class="o">-</code> <code class="n">ascent</code> <code class="o">-</code> <code class="n">PAD</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setPaint</code><code class="o">(</code><code class="n">Color</code><code class="o">.</code><code class="na">green</code><code class="o">);</code> <code class="c1">// Ascent line</code>
<code class="n">drawLine</code><code class="o">(</code><code class="n">g2</code><code class="o">,</code> <code class="n">x</code> <code class="o">-</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code> <code class="o">-</code> <code class="n">ascent</code><code class="o">,</code>
<code class="n">x</code> <code class="o">+</code> <code class="n">messageWidth</code> <code class="o">+</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code> <code class="o">-</code> <code class="n">ascent</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">setPaint</code><code class="o">(</code><code class="n">Color</code><code class="o">.</code><code class="na">red</code><code class="o">);</code> <code class="c1">// Descent line</code>
<code class="n">drawLine</code><code class="o">(</code><code class="n">g2</code><code class="o">,</code> <code class="n">x</code> <code class="o">-</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code> <code class="o">+</code> <code class="n">descent</code><code class="o">,</code>
<code class="n">x</code> <code class="o">+</code> <code class="n">messageWidth</code> <code class="o">+</code> <code class="n">PAD</code><code class="o">,</code> <code class="n">y</code> <code class="o">+</code> <code class="n">descent</code><code class="o">);</code>
<code class="o">}</code>
<code class="kd">private</code> <code class="kt">void</code> <code class="nf">drawLine</code><code class="o">(</code><code class="n">Graphics2D</code> <code class="n">g2</code><code class="o">,</code>
<code class="kt">double</code> <code class="n">x0</code><code class="o">,</code> <code class="kt">double</code> <code class="n">y0</code><code class="o">,</code> <code class="kt">double</code> <code class="n">x1</code><code class="o">,</code> <code class="kt">double</code> <code class="n">y1</code><code class="o">)</code> <code class="o">{</code>
<code class="n">Shape</code> <code class="n">line</code> <code class="o">=</code> <code class="k">new</code> <code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">geom</code><code class="o">.</code><code class="na">Line2D</code><code class="o">.</code><code class="na">Double</code><code class="o">(</code><code class="n">x0</code><code class="o">,</code> <code class="n">y0</code><code class="o">,</code> <code class="n">x1</code><code class="o">,</code> <code class="n">y1</code><code class="o">);</code>
<code class="n">g2</code><code class="o">.</code><code class="na">draw</code><code class="o">(</code><code class="n">line</code><code class="o">);</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code><code class="n">String</code> <code class="n">args</code><code class="o">[])</code> <code class="o">{</code>
<code class="n">String</code> <code class="n">message</code> <code class="o">=</code> <code class="s">"Lemming"</code><code class="o">;</code>
<code class="k">if</code> <code class="o">(</code><code class="n">args</code><code class="o">.</code><code class="na">length</code> <code class="o">></code> <code class="mi">0</code><code class="o">)</code> <code class="n">message</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">];</code>
<code class="n">JFrame</code> <code class="n">frame</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JFrame</code><code class="o">(</code><code class="s">"FontShow"</code><code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setSize</code><code class="o">(</code><code class="mi">420</code><code class="o">,</code> <code class="mi">300</code><code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setDefaultCloseOperation</code><code class="o">(</code> <code class="n">JFrame</code><code class="o">.</code><code class="na">EXIT_ON_CLOSE</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">.</code><code class="na">getContentPane</code><code class="o">().</code><code class="na">add</code><code class="o">(</code><code class="k">new</code> <code class="n">FontShow</code><code class="o">(</code><code class="n">message</code><code class="o">));</code>
<code class="n">frame</code><code class="o">.</code><code class="na">setVisible</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code></pre><div class="figure"><a id="learnjava3-CHP-20-FIG-3"/><div class="figure-contents"><div class="mediaobject"><a id="I_20_tt1159"/><img src="httpatomoreillycomsourceoreillyimages1707693.png" alt="The FontShow application"/></div></div><p class="title">Figure 20-3. The FontShow application</p></div><p>You can specify the text to be displayed as a command-line
argument:</p><a id="I_20_tt1158"/><pre class="programlisting"> <code class="o">%</code> <strong class="userinput"><code><code class="n">java</code> <code class="n">FontShow</code> <code class="s">"When in the course of human events ..."</code></code></strong></pre><p><code class="literal">FontShow</code> may look a bit
complicated, but there’s really not much to it. The bulk of the code is
in <code class="literal">paint()</code>, which sets the font,
draws the text, and adds a few lines to illustrate some of the font’s
characteristics (metrics). For fun, we also catch mouse clicks (using an
event handler defined in the constructor) and alternate the font size by
setting the <code class="literal">bigFont</code> toggle variable
and repainting.</p><p>By default, text is rendered above and to the right of the
coordinates specified in the <code class="literal">drawString()</code> method. Think of that starting
point as the origin of a coordinate system; the axes are the <a id="I_indexterm20_id812852" class="indexterm"/><span class="emphasis"><em>baselines</em></span> of the font. <code class="literal">FontShow</code> draws these lines in white. The
greatest height the characters stretch above the baseline is called the
<a id="I_indexterm20_id812867" class="indexterm"/><span class="emphasis"><em>ascent</em></span> and is shown by a green line.
Some fonts also have parts of letters that fall below the baseline. The
farthest distance any character reaches below the baseline is called the
<a id="I_indexterm20_id812877" class="indexterm"/><span class="emphasis"><em>descent</em></span>, which is illustrated with a
red line.</p><p>We ask for the ascent and descent of our font with the <code class="literal">LineMetrics</code> class’s <code class="literal">getAscent()</code> and <code class="literal">getDescent()</code> methods. We also ask for the
width of our string (when rendered in this font) with <code class="literal">Font</code>’s <a id="I_indexterm20_id812911" class="indexterm"/><code class="literal">getStringBounds()</code>
method. This information is used to center the word in the display area.
To center the word vertically, we use the height and adjust with the
descent to calculate the baseline location. <a class="xref" href="ch20s06.html#learnjava3-CHP-20-TABLE-2" title="Table 20-2. LineMetrics methods">Table 20-2</a> provides a short list of methods
that return useful font metrics.</p><div class="table"><a id="learnjava3-CHP-20-TABLE-2"/><p class="title">Table 20-2. LineMetrics methods</p><div class="table-contents"><table summary="LineMetrics methods" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Method</p></th><th style="text-align: left"><p>Description</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm20_id812974" class="indexterm"/> <code class="literal">getAscent()</code>
</p></td><td style="text-align: left"><p>Height above baseline</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm20_id812998" class="indexterm"/> <code class="literal">getDescent()</code>
</p></td><td style="text-align: left"><p>Depth below baseline</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm20_id813021" class="indexterm"/> <code class="literal">getLeading()</code>
</p></td><td style="text-align: left"><p>Standard vertical spacing between
lines</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm20_id813045" class="indexterm"/> <code class="literal">getHeight()</code>
</p></td><td style="text-align: left"><p>Total line height (ascent + descent +
leading)</p></td></tr></tbody></table></div></div><p><span class="emphasis"><em>Leading space</em></span> is the padding between lines of
text. The <code class="literal">getHeight()</code> method reports
the total height of a line of text, including the leading
space.<a id="I_indexterm20_id813073" class="indexterm"/><a id="I_indexterm20_id813080" class="indexterm"/></p></div></div></body></html>