一、场景需求
将一段文字通过Graphics类写到图片中时,需要知道这段文字的长度和宽度,用以确定最终生成的图片的长度和宽度。
二、jdk8实现方案
对于字体
Font font = new Font(FONT_NAME, FONT_STYLE, FONT_SIZE);
1、使用sun.font.FontDesignMetrics类中的方法
获取宽度,包括字符串的、字符的、字符数组的。
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
String text = "text for test";
int textWidth = metrics.stringWidth(text, 0, text.length());
int charWidth = metrics.charWidth('a');
int charsWidth = metrics.charsWidth(text.toCharArray(), 0, text.length());
获取高度
metrics.getHeight();
2、java.awt.Toolkit#getFontMetrics方法,拿到 Metrics后,方法同上。但是这个方法已经弃用了:
replaced by the Font method getLineMetrics
被Font类中的java.awt.Font#getLineMetrics方法替代,该方法有多个重载。而最终得到的LineMetrics对象信息中也无法获取我们想要的宽度,高度可以拿到。
三、一个问号
在jdk11中,sun.font.FontDesignMetrics这个类,它有点奇怪:
提示信息为:Package 'sun.font' is declared in module 'java.desktop', which does not export it to the unnamed module
意思是sun.font这个包是在java.desktop模块中声明的,但它并未被导出到当前这个未命名的模块
解决方案提示为:Add '--add-exports java.desktop/sun.font=ALL-UNNAMED' to module compiler options
意思是需要在编译参数中加上这个参数(点一下自己就加上了): --add-exports java.desktop/sun.font=ALL-UNNAMED
加上它以后确实是可以了:
然后在java编译参数中可以看到多了这么一项:
四、两个问号
这东西,是jdk9实装了模块系统概念以后,这个包属于别的模块(java.desktop),才导致的吗?在idea开发环境是可以用了,在非开发的jdk11环境中,能编译通过吗?打jar包以后能正常运行吗?还是说打包时要加什么参数?或者运行时加什么参数?在以后的jdk中会被弃用吗?
以后有时间再试试。
五、替代方案
最终找寻一个替代方案:
FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
Rectangle rec = STRING_FONT.getStringBounds("a", frc).getBounds();
double height = rec.getHeight();
double width = rec.getWidth();
满足了需求,做一个记录。