简介:本文详细介绍如何在Java中加载字体库、实现竖排文字布局,并通过Graphics2D实现文字描边效果,包含完整代码示例与优化建议。
Java通过java.awt.Font类支持多种字体格式,包括TrueType(.ttf)、OpenType(.otf)和PostScript Type1(.pfb)。推荐使用TrueType格式,因其跨平台兼容性最佳。
// 从文件系统加载字体File fontFile = new File("path/to/custom.ttf");Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontFile);// 设置字体样式和大小customFont = customFont.deriveFont(Font.BOLD, 24f);
通过GraphicsEnvironment实现字体全局注册,确保程序各处均可使用:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();ge.registerFont(customFont);
try {Font font = Font.createFont(Font.TRUETYPE_FONT, new File("invalid.ttf"));} catch (FontFormatException e) {System.err.println("字体格式不正确: " + e.getMessage());} catch (IOException e) {System.err.println("文件读取失败: " + e.getMessage());}
利用AffineTransform实现90度旋转,配合Y轴反向变换:
AffineTransform transform = new AffineTransform();transform.translate(100, 300); // 定位基点transform.rotate(Math.PI/2); // 90度旋转Graphics2D g2d = (Graphics2D) graphics;g2d.setTransform(transform);
String text = "竖排文字示例";int x = 0;int lineHeight = 30;for (int i = 0; i < text.length(); i++) {char c = text.charAt(i);g2d.drawString(String.valueOf(c), x, i * lineHeight);}
对于包含阿拉伯语等从右向左文本的混合排版,需设置ComponentOrientation:
JComponent component = new JPanel();component.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
通过叠加不同颜色的文字实现描边效果:
public void drawOutlinedText(Graphics2D g, String text, int x, int y) {// 设置描边参数g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 描边层(外轮廓)g.setColor(Color.BLACK);g.setFont(g.getFont().deriveFont(Font.BOLD, 24f));for (int i = -2; i <= 2; i++) {for (int j = -2; j <= 2; j++) {if (i != 0 || j != 0) { // 排除中心点g.drawString(text, x + i, y + j);}}}// 填充层g.setColor(Color.WHITE);g.drawString(text, x, y);}
使用TextLayout和Area实现更精确的描边:
public void drawAdvancedOutline(Graphics2D g, String text, int x, int y) {FontRenderContext frc = g.getFontRenderContext();TextLayout layout = new TextLayout(text, g.getFont(), frc);// 创建轮廓Shape outline = layout.getOutline(null);AffineTransform at = AffineTransform.getTranslateInstance(x, y);outline = at.createTransformedShape(outline);// 描边g.setColor(Color.RED);g.setStroke(new BasicStroke(3));((Graphics2D)g).draw(outline);// 填充g.setColor(Color.YELLOW);((Graphics2D)g).fill(outline);}
volatileImage进行离屏渲染BufferedImageRenderingHints平衡质量与速度
import java.awt.*;import java.awt.font.*;import java.awt.geom.*;import java.io.*;import javax.swing.*;public class VerticalTextWithOutline extends JPanel {private Font customFont;public VerticalTextWithOutline() {try {// 加载字体customFont = Font.createFont(Font.TRUETYPE_FONT,new File("simsun.ttc")).deriveFont(Font.BOLD, 24f);GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(customFont);} catch (Exception e) {customFont = new Font("宋体", Font.BOLD, 24);}}@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);Graphics2D g2d = (Graphics2D) g;g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);String text = "竖排文字描边示例";int x = 50;int y = 300;int lineHeight = 30;// 设置变换AffineTransform oldTransform = g2d.getTransform();g2d.translate(x, y);g2d.rotate(Math.PI/2);// 描边效果g2d.setColor(Color.BLUE);g2d.setFont(customFont);for (int i = 0; i < text.length(); i++) {char c = text.charAt(i);// 描边层for (int dx = -2; dx <= 2; dx++) {for (int dy = -2; dy <= 2; dy++) {if (dx != 0 || dy != 0) {g2d.drawString(String.valueOf(c), dx, i * lineHeight + dy);}}}// 填充层g2d.setColor(Color.WHITE);g2d.drawString(String.valueOf(c), 0, i * lineHeight);}g2d.setTransform(oldTransform);}public static void main(String[] args) {JFrame frame = new JFrame("竖排文字描边示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 500);frame.add(new VerticalTextWithOutline());frame.setVisible(true);}}
Font.canDisplayUpTo()方法检测FontMetrics的字符高度TextLayout获取精确尺寸本方案通过系统化的字体处理、精确的坐标变换和高效的描边算法,实现了高质量的竖排文字渲染效果。实际应用中可根据具体需求调整参数,如描边宽度、旋转角度等,以获得最佳视觉效果。