Jazz up the standard Java fonts

本文介绍了运用标准Java字体让网站脱颖而出的技巧。包括显示系统字体、定位点,还阐述了添加阴影、雕刻文本、字母描边等七种绘制技巧,最后提到这些技巧有一定局限性,开发者可创建自定义组件,还能结合图像处理技术实现更酷效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


A few simple tricks applied to standard Java fonts can help make your Web site stand out from the crowd. With the basic knowledge presented here, you will be able to create a set of font styles richer than the standard plain, bold, and italic. And do not confine yourself to these ideas -- they just lay the groundwork. You only need a limited mathematical background to understand the computations. So read on and discover the possibilities!

Display your system fonts
Before I proceed, you need to find out what fonts are available on your system. These can vary between Java Virtual Machine (JVM) implementations. The following code displays the names of all the fonts available on a particular JVM. The screenshot on the right illustrates the fonts available on my PC. Yours may look different.



String [] fonts = getToolkit().getFontList();
Font font;
int font_size = 20;
int x = 20;
int y = 25;
int line_spacing = 25;
for (int i = 0; i < fonts.length; i++)
   {
   font = new Font(fonts[i], Font.BOLD, font_size);
   g.setFont(font);
   g.drawString(fonts[i], x, y);
   y += line_spacing;
   }

Position the points
For most of the seven drawing tricks in this article you duplicate the text, slightly reposition it, and color the duplicate appropriately. The image on the right shows eight positions surrounding a center point. On the horizontal axis x increases from west to east, and on the vertical axis y increases from north to south. For example, the coordinate for the northeast position is (x + 1, y - 1) if the center is (x, y). I'll use the positions of this image in explaining the drawing tricks. The coordinate for the center position is assumed to be (x, y).

The following functions are used to improve code readability:


    
int ShiftNorth(int p, int distance) {
   return (p - distance);
   }

int ShiftSouth(int p, int distance) {
   return (p + distance);
   }

int ShiftEast(int p, int distance) {
   return (p + distance);
   }

int ShiftWest(int p, int distance) {
   return (p - distance);
   }

Add a shadow
The easiest trick adds a shadow to the text. Use a dark color for the shadow and draw it near the center. Then draw the text in the center with its color on top of the shadow. The example here shows a shadow two points away in a southeasterly direction. The light looks as if it's coming from the northwest.



g.setColor(new Color(50, 50, 50));
g.drawString("Shadow", ShiftEast(x, 2), ShiftSouth(y, 2));
g.setColor(new Color(220, 220, 220));
g.drawString("Shadow", x, y);

Engrave the text
You can achieve an engraved effect by using a darker color for the background than for the text. To emulate a light projected on the inner walls of the engraved text, use a brighter color and draw it near the center. Finally, draw the text in the center.

The example here draws the inner walls one point southeast of the center with the light coming from the northwest. This effect relies heavily on color selection, so be careful!



g.setColor(new Color(220, 220, 220));
g.drawString("Engrave", ShiftEast(x, 1), ShiftSouth(y, 1));
g.setColor(new Color(50, 50, 50));
g.drawString("Engrave", x, y);

Outline the letters
You can outline the text by first drawing it at the northwest, southwest, northeast, and southeast positions with the outline color and then drawing the text in the center with the text color. The example here does exactly that with a red outline color and a yellow text color.



g.setColor(Color.red);
g.drawString("Outline", ShiftWest(x, 1), ShiftNorth(y, 1));
g.drawString("Outline", ShiftWest(x, 1), ShiftSouth(y, 1));
g.drawString("Outline", ShiftEast(x, 1), ShiftNorth(y, 1));
g.drawString("Outline", ShiftEast(x, 1), ShiftSouth(y, 1));
g.setColor(Color.yellow);
g.drawString("Outline", x, y);

Hollow them out
Hollowing is nearly the same as outlining. When you draw the text in the center, use the background color instead. That way, only the contour of the text appears. In the example, bg is the background color used to draw the text.



g.setColor(Color.black);
g.drawString("Hollow", ShiftWest(x, 1), ShiftNorth(y, 1));
g.drawString("Hollow", ShiftWest(x, 1), ShiftSouth(y, 1));
g.drawString("Hollow", ShiftEast(x, 1), ShiftNorth(y, 1));
g.drawString("Hollow", ShiftEast(x, 1), ShiftSouth(y, 1));
g.setColor(bg);
g.drawString("Hollow", x, y);

Cut them into segments
An IBM-logo effect requires two major steps. First you carefully measure the font dimensions. Then you draw the horizontal lines on the text with the background color at computed positions. You start those lines from below the descenders.

The following example uses bg as the background color. For each interval of three pixels, it draws a line from below the font's descenders (descent) and moves up until the ascenders (height) are reached. The string width is w, the ascender height is h, and the descender is d.



int w = (g.getFontMetrics()).stringWidth("Segment");
int h = (g.getFontMetrics()).getHeight();
int d = (g.getFontMetrics()).getDescent();
g.setColor(new Color(220, 220, 220));
g.drawString("Segment", x, y);
g.setColor(bg);
for (int i = 0; i < h; i += 3)
   g.drawLine(x, y + d - i, x + w, y + d - i);

Open a third dimension
To achieve a three-dimensional effect, you first choose a color slightly darker than the text; then, for the main shadow, choose a second color much darker than the text. Duplicate the text in one color along one direction (say, north) and in the other color along another direction (say, west). This process results in two shadow faces for the text.

Finally, you draw the text in the center with its color on top of the shadows. The example here uses yellow as the text color and two darker yellows as the shadows. The thickness of the text is 5. The light comes roughly from the southeast.



Color top_color = new Color(200, 200, 0);
Color side_color = new Color(100, 100, 0);
for (int i = 0; i < 5; i++) {
   g.setColor(top_color);
   g.drawString("3-Dimension", ShiftEast(x, i), ShiftNorth(ShiftSouth(y, i), 1));
   g.setColor(side_color);
   g.drawString("3-Dimension", ShiftWest(ShiftEast(x, i), 1), ShiftSouth(y, i));
   }
g.setColor(Color.yellow);
g.drawString("3-Dimension", ShiftEast(x, 5), ShiftSouth(y, 5));

Put the words in motion
The idea behind this effect is enlarging the font larger as the text approaches the viewer. At the same time the text color should be darker, the farther it is from the viewer. Also, you need to draw the text from far to near so you don't block any part of the closest image. The example uses green as the text color. It increases the font size and makes the color brighter at a specified speed. width is the window width and w is the string width. This example centers the text and redraws it 20 times.



  for (int i = 0; i < 20; i++) {
         font_size = 12 + i;
         g.setFont(new Font("TimesRoman", Font.PLAIN, font_size));
         w = (g.getFontMetrics()).stringWidth("Motion");
         g.setColor(new Color(0, 65 + i * 10, 0));
         g.drawString("Motion", (width - w) / 2, ShiftSouth(y, speed * i));        
         }

 

 

Create your own effects
This article is intended to inspire you with a few codes that create font styles, but there are limitations. For example, the engraving effect does not work with many colors. Also, some GUI components are not always able to incorporate these effects. That means you may want to make a set of your own GUI components. In fact, building a set of such components is one of the major applications you can use in the future. Another application might use the same techniques in a general drawing context to embellish text buttons, borders, bars, and other geometric shapes. Other possibilities include animations, snazzy titles, logos, and so forth. More advanced developers can probably apply image processing techniques to make even cooler effects.

<think>我们正在讨论JVM如何加载本地字体,特别是关于JAVA_FONTS的机制和配置方法。根据引用[3]和[4],我们知道在Java应用程序中,字体问题可能会导致异常,例如`JRFontNotFoundException`。因此,了解JVM加载字体的机制和如何配置JAVA_FONTS非常重要。 ### JVM字体加载机制 JVM在启动时会加载系统可用的字体。在Java中,字体管理是通过`java.awt.Font`类和相关类实现的。JVM会从以下位置加载字体: 1. **JRE的`lib/fonts`目录**:这是JRE自带的字体目录。 2. **操作系统字体目录**:例如,在Windows上是`C:\Windows\Fonts`,在Linux上是`/usr/share/fonts`等。 3. **用户自定义字体目录**:可以通过设置系统属性或环境变量来指定额外的字体目录。 其中,环境变量`JAVA_FONTS`就是用来指定额外的字体目录的。当设置了`JAVA_FONTS`后,JVM会将该变量指定的目录添加到字体搜索路径中。 ### 配置JAVA_FONTS的方法 要配置`JAVA_FONTS`,你可以在启动JVM之前设置环境变量。具体方法取决于你的操作系统和启动方式。 #### 在Linux/Unix系统中 1. **临时设置**:在终端中执行命令时设置环境变量。 ```bash export JAVA_FONTS=/path/to/your/fonts/directory java -jar your_application.jar ``` 2. **永久设置**:将`export JAVA_FONTS=/path/to/your/fonts/directory`添加到你的shell配置文件(如`~/.bashrc`或`~/.profile`)中,然后执行`source ~/.bashrc`使其生效。 #### 在Windows系统中 1. **临时设置**:在命令提示符中设置。 ```cmd set JAVA_FONTS=C:\path\to\your\fonts\directory java -jar your_application.jar ``` 2. **永久设置**:通过系统属性设置环境变量。 - 右键点击“此电脑” -> “属性” -> “高级系统设置” -> “环境变量” -> 在“系统变量”或“用户变量”中新建变量`JAVA_FONTS`,值为字体目录的路径。 ### 验证字体加载 你可以通过以下Java代码来验证JVM是否成功加载了字体: ```java import java.awt.Font; import java.awt.GraphicsEnvironment; public class ListFonts { public static void main(String[] args) { Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); for (Font font : fonts) { System.out.println(font.getFontName()); } } } ``` 运行这段代码将列出JVM当前可用的所有字体名称。确保你设置的字体目录中的字体出现在列表中。 ### 注意事项 1. 如果字体文件是TrueType(.ttf)或OpenType(.otf)格式,JVM通常能够加载它们。 2. 在Linux系统中,有时需要刷新字体缓存(使用`fc-cache -fv`)才能使新添加的字体生效,但JVM的`JAVA_FONTS`目录通常不需要刷新系统字体缓存,因为JVM会直接取该目录。 3. 如果使用Docker等容器环境,需要确保容器内存在字体文件,并正确设置`JAVA_FONTS`环境变量。 ### 引用说明 在Java应用程序中,字体问题是一个常见的问题,特别是在生成PDF或图像时。通过正确配置`JAVA_FONTS`,可以避免诸如`Font '宋体' is not available to the JVM`这样的异常[^4]。 §§相关问题§§ 1. JVM在启动时加载字体的具体过程是怎样的? 2. 除了设置JAVA_FONTS,还有哪些方法可以让JVM识别自定义字体? 3. 在容器化环境中如何配置JVM字体?</think>### JVM加载本地JAVA_FONTS的机制与配置方法 #### 一、加载机制 JVM通过以下路径搜索字体文件: 1. **默认字体目录**:`$JAVA_HOME/lib/fonts`(JRE内置字体) 2. **操作系统字体目录**: - Windows:`C:\Windows\Fonts` - Linux:`/usr/share/fonts/` - macOS:`/Library/Fonts/` 3. **JAVA_FONTS环境变量路径**:用户自定义的字体目录[^3][^4] 4. **用户级字体目录**:如Linux的`~/.local/share/fonts/` 加载流程: 1. JVM启动时初始化`sun.font.FontManager` 2. 扫描上述路径的字体文件(.ttf/.ttc/.otf等) 3. 建立字体名到字体文件的映射关系 4. 通过`java.awt.Font`类提供字体服务 #### 二、配置方法 **1. 设置环境变量(推荐)** ```bash # Linux/macOS export JAVA_FONTS=/path/to/custom/fonts java -jar yourapp.jar # Windows set JAVA_FONTS=C:\custom_fonts java -jar yourapp.jar ``` **2. JVM参数配置** ```bash java -Djava.awt.fonts=/path/to/fonts -Dsun.java2d.fontpath=/path/to/fonts ... ``` **3. 程序内加载(代码级)** ```java // 动态注册字体 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("font.ttf"))); ``` #### 三、常见问题解决 **字体缺失异常处理**: 当出现`Font 'xxx' is not available to the JVM`错误时: 1. 确认字体文件已放入`JAVA_FONTS`目录 2. 检查文件权限:`chmod 644 *.ttf`(Linux) 3. 清除字体缓存:删除`~/.java/fonts`目录 4. 验证字体格式:`file font.ttf`(应显示TrueType/OpenType) **容器环境配置**: 在Docker中需确保: ```Dockerfile COPY fonts/ /usr/share/fonts/custom/ ENV JAVA_FONTS=/usr/share/fonts/custom ``` #### 四、验证配置 ```java // 检查可用字体 Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); Arrays.stream(fonts).map(Font::getName).forEach(System.out::println); ``` > **关键点**:JVM优先加载`JAVA_FONTS`路径的字体,该目录应包含完整的字体文件(如simsun.ttf),而非仅字体名[^4]。对于中文环境,宋体/黑体等需显式提供。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值