Calibri 字体在 <html> 文本移动到组件的底部
Calibri Font when in <html> text moves to the bottom part of the component
没有太多要解释的。请看下面的 MCVE/image:
public class FontExample extends JFrame {
private static final Font FONT = new Font("Calibri", Font.PLAIN, 14);
public FontExample() {
super("");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setFont(FONT);
withoutHtml.setBorder(BorderFactory.createLineBorder(Color.red));
add(withoutHtml);
JLabel withHtml = new JLabel("<html><body style='vertical-align:top;'>hello Whosebug");
withHtml.setBorder(BorderFactory.createLineBorder(Color.green));
withHtml.setFont(FONT);
add(withHtml);
setLocationByPlatform(true);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
//Make sure Calibri font is installed
if (!"Calibri".equals(FONT.getFamily())) {
System.err.println("Font calibri is not installed.");
System.exit(1);
}
new FontExample().setVisible(true);
});
}
}
绿色的带有 <html>
标签。 有没有办法修复它? 并且通过修复,我的意思是让它像左边那个一样,没有这个愚蠢的东西space?
其他任何字体似乎都不会发生这种情况(我又测试了 2-3 种)。我在 Java 8 和 Windows 7 和 Windows 10.
我尝试在底部添加填充:
JLabel withHtml = new JLabel("<html><body style='padding-bottom:5px'>hello Whosebug");
正如预期的那样,我得到的是:
其中 a) 将拧紧同一容器中其他组件的对齐方式(不利于 UI 目的)并且 b) 我将不得不对自 5 以来的许多值进行硬编码,因为这是正确的字体大小14。但对于其他字体大小,它需要另一个值。
@Andrew Thomson 在评论中说对所有 JLabel 使用 HTML 格式。但是,如果它们紧挨着另一个基于文本的组件,例如 JTextField
,我会得到:
这显然也很糟糕。
更新
此外,我尝试从网上下载 Calibri 字体(以及 "Calibri Light" 等变体)并按照 in this question 所述进行安装。我不知道 "Overrides" 是否是现有的,但我得到了相同的结果。
有两种方法可以解决这个问题,添加
html {
margin:0;
}
或向文本的两个位添加填充。 :)
当然你可以试试
<html style="margin:0;">
<body style='vertical-align:text-bottom;'
对我有用,但如果我误解了你的问题,你可以在 https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
找到其他值
一行文字由三部分组成:
为了看得更清楚,我用了50号的Calibri,没有HTML的标签是:
在HTML模式下,情况有所不同。 HTML 渲染器将前导 放在第一位 (出于某种原因):
这给出了您观察到的令人不快的结果。
现在你会问"But why do I see that effect only with Calibri?"其实所有的字体都有这个效果,只是通常小很多,所以你没有注意到。
这是一个输出一些常见 Windows 字体指标的程序:
import java.awt.*;
import javax.swing.JLabel;
public class FontInfo
{
static void info(String family, int size)
{
Font font = new Font(family, Font.PLAIN, size);
if(!font.getFamily().equals(family))
throw new RuntimeException("Font not available: "+family);
FontMetrics fm = new JLabel().getFontMetrics(font);
System.out.printf("%-16s %2d %2d %2d\n", family, fm.getAscent(), fm.getDescent(), fm.getLeading());
}
public static void main(String[] args)
{
String[] fonts = {"Arial", "Calibri", "Courier New", "Segoe UI", "Tahoma", "Times New Roman", "Verdana"};
System.out.printf("%-16s %s\n", "", " A D L");
for(String f : fonts)
info(f, 50);
}
}
对于 50 码,结果为:
A D L
Arial 46 11 2
Calibri 38 13 11
Courier New 42 15 0
Segoe UI 54 13 0
Tahoma 50 11 0
Times New Roman 45 11 2
Verdana 51 11 0
如您所见,与其他字体相比,Calibri 的行距很大。
对于尺寸 14,结果为:
A D L
Arial 13 3 1
Calibri 11 4 3
Courier New 12 5 0
Segoe UI 16 4 0
Tahoma 14 3 0
Times New Roman 13 3 1
Verdana 15 3 0
Calibri 的前导仍然是 3 个像素。其他字体有0或1,表示对它们的影响不明显或很小。
似乎无法更改 HTML 渲染器的行为。但是,如果目标是对齐相邻组件的基线,那么这是可能的。您使用的 FlowLayout
有一个 alignOnBaseline
属性。如果启用它,它会正确对齐组件:
更新 1
这里的 JFixedLabel
class 给出了相同的结果,无论它包含 HTML 还是纯文本。它在 HTML 模式下将 Graphics
转换为主值:
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicHTML;
public class JFixedLabel extends JLabel
{
public JFixedLabel(String text)
{
super(text);
}
@Override
protected void paintComponent(Graphics g)
{
int dy;
if(getClientProperty(BasicHTML.propertyKey)!=null)
dy = getFontMetrics(getFont()).getLeading();
else
dy = 0;
g.translate(0, -dy);
super.paintComponent(g);
g.translate(0, dy);
}
}
结果:
更新 2
之前的解决方案存在图标问题,因此这里有一个新的解决方案可以同时处理文本和图标。这里我们不扩展JLabel
,而是定义一个新的UI class:
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.metal.MetalLabelUI;
public class FixedLabelUI extends MetalLabelUI
{
@Override
protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text, Icon icon,
Rectangle viewR, Rectangle iconR, Rectangle textR)
{
String res = super.layoutCL(label, fontMetrics, text, icon, viewR, iconR, textR);
if(label.getClientProperty(BasicHTML.propertyKey)!=null)
textR.y -= fontMetrics.getLeading();
return res;
}
}
要将 UI 分配给标签,请执行以下操作:
JLabel label = new JLabel();
label.setUI(new FixedLabelUI());
Olivier's answer 建议使用 flowLayout.setAlignOnBaseline(true);
但它不会在其他 Layoutmanagers 中工作,例如 GridLayout
。但是,它帮助我 很多 找到了我正在寻找的确切解决方案。即使它是 messy/hacky 个。
这里是:
如果你 System.out.println(label.getFontMetrics(label.getFont()))
,你会看到 FontMetrics
的实际 class 是 FontDesignMetrics。对我们来说幸运的是,值 ascent
、descent
和 leading
的 getter 依赖于字段而没有进行一些疯狂的计算。对我们 vol.2 来说幸运的是,对于相同的字体,这些字体指标是相同的 (equals
)。这意味着,对于每个 Font style-size 组合(显然是它的家族),我们有一个 FontDesignMetrics
实例。
换句话说:
private static final Font FONT = new Font("Calibri", Font.PLAIN, 50);
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setFont(FONT);
add(withoutHtml);
JLabel withHtml = new JLabel("<html>hello Whosebug");
withHtml.setFont(FONT);
FontMetrics withHtmlFontMetrics = withHtml.getFontMetrics(withHtml.getFont());
FontMetrics withoutHtmlFontMetrics = withoutHtml.getFontMetrics(withoutHtml.getFont());
boolean equals = withHtmlFontMetrics.equals(withoutHtmlFontMetrics);
System.out.println(equals);
即使在不同的标签中调用了 getFontMetrics
,它也会打印 true
。如果你 withHtml.setFont(FONT.deriveFont(Font.BOLD));
你会看到它打印 false
。因为字体不同,我们有不同的字体指标实例。
修复
(免责声明:危急时刻需要采取危急措施)
正如我已经提到的,它有点老套并且依赖于 reflection
。使用 reflection
我们可以操纵这 3 个值。类似于:
FontMetrics fontMetrics = label.getFontMetrics(label.getFont());
Field descentField = fontMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(fontMetrics, 0);
但是您要为每种字体 size/style 硬编码值,或者您可以按照我的做法进行操作。
我所做的是从其他字体的 FontMetrics
复制这些值。看起来在 Calibri
字体的情况下,Tahoma
就是那个。
首先,创建更改字段值的方法,取自 Tahoma 字体指标:
private static void copyTahomaFontMetricsTo(JComponent component) {
try {
FontMetrics calibriMetrics = component.getFontMetrics(component.getFont());
// Create a dummy JLabel with tahoma font, to obtain tahoma font metrics
JLabel dummyTahomaLabel = new JLabel();
dummyTahomaLabel.setFont(new Font("Tahoma", component.getFont().getStyle(), component.getFont().getSize()));
FontMetrics tahomaMetrics = dummyTahomaLabel.getFontMetrics(dummyTahomaLabel.getFont());
Field descentField = calibriMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(calibriMetrics, tahomaMetrics.getDescent());
Field ascentField = calibriMetrics.getClass().getDeclaredField("ascent");
ascentField.setAccessible(true);
ascentField.set(calibriMetrics, tahomaMetrics.getAscent());
Field leadingField = calibriMetrics.getClass().getDeclaredField("leading");
leadingField.setAccessible(true);
leadingField.set(calibriMetrics, tahomaMetrics.getLeading());
} catch (Exception e) {
e.printStackTrace();
}
}
现在,用 copyTahomaFontMetricsTo(withHtml);
来称呼它,而不关心它是 withHtml
标签还是 withoutHtml
,因为 它们都具有相同的字体。
结果(框架标题中的字体大小):
即使旁边还有其他 text-based 个组件:
如您所见,它成功了!再加上布局对齐没有搞砸。
看起来很完美,其实不然。
同样,如前所述,对于每种字体(family
、size
和 style
的组合),都有一个 FontMetrics
实例。将其中一个标签的字体更改为 Font.BOLD
将阻止我们获得完美对齐。可能错过一个(或两个)像素。另外,对于 Bold
,我们还必须 copyTahomaFontMetricsTo
:
copyTahomaFontMetricsTo(withoutBoldFont);
copyTahomaFontMetricsTo(withBoldFont);
和结果(框架标题上的字体大小):
仔细看:
有一个像素的差异。但我想我会接受它,因为这比 Swing's/Windows 默认 Calibri-HTML 行为好(方式):
完整示例:
public class FontExample extends JFrame {
private static final Font FONT = new Font("Calibri", Font.PLAIN, 20);
public FontExample() {
super("Font: " + FONT.getSize());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setBorder(BorderFactory.createLineBorder(Color.GREEN));
withoutHtml.setFont(FONT.deriveFont(Font.BOLD));
add(withoutHtml);
JLabel withHtml = new JLabel("<html>hello Whosebug");
withHtml.setBorder(BorderFactory.createLineBorder(Color.RED));
withHtml.setFont(FONT);
copyTahomaFontMetricsTo(withoutHtml);
copyTahomaFontMetricsTo(withHtml);
add(withHtml);
setLocationByPlatform(true);
pack();
}
private static void copyTahomaFontMetricsTo(JLabel label) {
try {
FontMetrics calibriMetrics = label.getFontMetrics(label.getFont());
// Create a dummy JLabel with tahoma font, to obtain tahoma font metrics
JLabel dummyTahomaLabel = new JLabel();
dummyTahomaLabel.setFont(new Font("Tahoma", label.getFont().getStyle(), label.getFont().getSize()));
FontMetrics tahomaMetrics = dummyTahomaLabel.getFontMetrics(dummyTahomaLabel.getFont());
Field descentField = calibriMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(calibriMetrics, tahomaMetrics.getDescent());
Field ascentField = calibriMetrics.getClass().getDeclaredField("ascent");
ascentField.setAccessible(true);
ascentField.set(calibriMetrics, tahomaMetrics.getAscent());
Field leadingField = calibriMetrics.getClass().getDeclaredField("leading");
leadingField.setAccessible(true);
leadingField.set(calibriMetrics, tahomaMetrics.getLeading());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new FontExample().setVisible(true);
});
}
}
没有太多要解释的。请看下面的 MCVE/image:
public class FontExample extends JFrame {
private static final Font FONT = new Font("Calibri", Font.PLAIN, 14);
public FontExample() {
super("");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setFont(FONT);
withoutHtml.setBorder(BorderFactory.createLineBorder(Color.red));
add(withoutHtml);
JLabel withHtml = new JLabel("<html><body style='vertical-align:top;'>hello Whosebug");
withHtml.setBorder(BorderFactory.createLineBorder(Color.green));
withHtml.setFont(FONT);
add(withHtml);
setLocationByPlatform(true);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
//Make sure Calibri font is installed
if (!"Calibri".equals(FONT.getFamily())) {
System.err.println("Font calibri is not installed.");
System.exit(1);
}
new FontExample().setVisible(true);
});
}
}
绿色的带有 <html>
标签。 有没有办法修复它? 并且通过修复,我的意思是让它像左边那个一样,没有这个愚蠢的东西space?
其他任何字体似乎都不会发生这种情况(我又测试了 2-3 种)。我在 Java 8 和 Windows 7 和 Windows 10.
我尝试在底部添加填充:
JLabel withHtml = new JLabel("<html><body style='padding-bottom:5px'>hello Whosebug");
正如预期的那样,我得到的是:
其中 a) 将拧紧同一容器中其他组件的对齐方式(不利于 UI 目的)并且 b) 我将不得不对自 5 以来的许多值进行硬编码,因为这是正确的字体大小14。但对于其他字体大小,它需要另一个值。
@Andrew Thomson 在评论中说对所有 JLabel 使用 HTML 格式。但是,如果它们紧挨着另一个基于文本的组件,例如 JTextField
,我会得到:
这显然也很糟糕。
更新
此外,我尝试从网上下载 Calibri 字体(以及 "Calibri Light" 等变体)并按照 in this question 所述进行安装。我不知道 "Overrides" 是否是现有的,但我得到了相同的结果。
有两种方法可以解决这个问题,添加
html {
margin:0;
}
或向文本的两个位添加填充。 :)
当然你可以试试
<html style="margin:0;">
<body style='vertical-align:text-bottom;'
对我有用,但如果我误解了你的问题,你可以在 https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
一行文字由三部分组成:
为了看得更清楚,我用了50号的Calibri,没有HTML的标签是:
在HTML模式下,情况有所不同。 HTML 渲染器将前导 放在第一位 (出于某种原因):
这给出了您观察到的令人不快的结果。
现在你会问"But why do I see that effect only with Calibri?"其实所有的字体都有这个效果,只是通常小很多,所以你没有注意到。
这是一个输出一些常见 Windows 字体指标的程序:
import java.awt.*;
import javax.swing.JLabel;
public class FontInfo
{
static void info(String family, int size)
{
Font font = new Font(family, Font.PLAIN, size);
if(!font.getFamily().equals(family))
throw new RuntimeException("Font not available: "+family);
FontMetrics fm = new JLabel().getFontMetrics(font);
System.out.printf("%-16s %2d %2d %2d\n", family, fm.getAscent(), fm.getDescent(), fm.getLeading());
}
public static void main(String[] args)
{
String[] fonts = {"Arial", "Calibri", "Courier New", "Segoe UI", "Tahoma", "Times New Roman", "Verdana"};
System.out.printf("%-16s %s\n", "", " A D L");
for(String f : fonts)
info(f, 50);
}
}
对于 50 码,结果为:
A D L Arial 46 11 2 Calibri 38 13 11 Courier New 42 15 0 Segoe UI 54 13 0 Tahoma 50 11 0 Times New Roman 45 11 2 Verdana 51 11 0
如您所见,与其他字体相比,Calibri 的行距很大。
对于尺寸 14,结果为:
A D L Arial 13 3 1 Calibri 11 4 3 Courier New 12 5 0 Segoe UI 16 4 0 Tahoma 14 3 0 Times New Roman 13 3 1 Verdana 15 3 0
Calibri 的前导仍然是 3 个像素。其他字体有0或1,表示对它们的影响不明显或很小。
似乎无法更改 HTML 渲染器的行为。但是,如果目标是对齐相邻组件的基线,那么这是可能的。您使用的 FlowLayout
有一个 alignOnBaseline
属性。如果启用它,它会正确对齐组件:
更新 1
这里的 JFixedLabel
class 给出了相同的结果,无论它包含 HTML 还是纯文本。它在 HTML 模式下将 Graphics
转换为主值:
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicHTML;
public class JFixedLabel extends JLabel
{
public JFixedLabel(String text)
{
super(text);
}
@Override
protected void paintComponent(Graphics g)
{
int dy;
if(getClientProperty(BasicHTML.propertyKey)!=null)
dy = getFontMetrics(getFont()).getLeading();
else
dy = 0;
g.translate(0, -dy);
super.paintComponent(g);
g.translate(0, dy);
}
}
结果:
更新 2
之前的解决方案存在图标问题,因此这里有一个新的解决方案可以同时处理文本和图标。这里我们不扩展JLabel
,而是定义一个新的UI class:
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.metal.MetalLabelUI;
public class FixedLabelUI extends MetalLabelUI
{
@Override
protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text, Icon icon,
Rectangle viewR, Rectangle iconR, Rectangle textR)
{
String res = super.layoutCL(label, fontMetrics, text, icon, viewR, iconR, textR);
if(label.getClientProperty(BasicHTML.propertyKey)!=null)
textR.y -= fontMetrics.getLeading();
return res;
}
}
要将 UI 分配给标签,请执行以下操作:
JLabel label = new JLabel();
label.setUI(new FixedLabelUI());
Olivier's answer 建议使用 flowLayout.setAlignOnBaseline(true);
但它不会在其他 Layoutmanagers 中工作,例如 GridLayout
。但是,它帮助我 很多 找到了我正在寻找的确切解决方案。即使它是 messy/hacky 个。
这里是:
如果你 System.out.println(label.getFontMetrics(label.getFont()))
,你会看到 FontMetrics
的实际 class 是 FontDesignMetrics。对我们来说幸运的是,值 ascent
、descent
和 leading
的 getter 依赖于字段而没有进行一些疯狂的计算。对我们 vol.2 来说幸运的是,对于相同的字体,这些字体指标是相同的 (equals
)。这意味着,对于每个 Font style-size 组合(显然是它的家族),我们有一个 FontDesignMetrics
实例。
换句话说:
private static final Font FONT = new Font("Calibri", Font.PLAIN, 50);
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setFont(FONT);
add(withoutHtml);
JLabel withHtml = new JLabel("<html>hello Whosebug");
withHtml.setFont(FONT);
FontMetrics withHtmlFontMetrics = withHtml.getFontMetrics(withHtml.getFont());
FontMetrics withoutHtmlFontMetrics = withoutHtml.getFontMetrics(withoutHtml.getFont());
boolean equals = withHtmlFontMetrics.equals(withoutHtmlFontMetrics);
System.out.println(equals);
即使在不同的标签中调用了 getFontMetrics
,它也会打印 true
。如果你 withHtml.setFont(FONT.deriveFont(Font.BOLD));
你会看到它打印 false
。因为字体不同,我们有不同的字体指标实例。
修复
(免责声明:危急时刻需要采取危急措施)
正如我已经提到的,它有点老套并且依赖于 reflection
。使用 reflection
我们可以操纵这 3 个值。类似于:
FontMetrics fontMetrics = label.getFontMetrics(label.getFont());
Field descentField = fontMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(fontMetrics, 0);
但是您要为每种字体 size/style 硬编码值,或者您可以按照我的做法进行操作。
我所做的是从其他字体的 FontMetrics
复制这些值。看起来在 Calibri
字体的情况下,Tahoma
就是那个。
首先,创建更改字段值的方法,取自 Tahoma 字体指标:
private static void copyTahomaFontMetricsTo(JComponent component) {
try {
FontMetrics calibriMetrics = component.getFontMetrics(component.getFont());
// Create a dummy JLabel with tahoma font, to obtain tahoma font metrics
JLabel dummyTahomaLabel = new JLabel();
dummyTahomaLabel.setFont(new Font("Tahoma", component.getFont().getStyle(), component.getFont().getSize()));
FontMetrics tahomaMetrics = dummyTahomaLabel.getFontMetrics(dummyTahomaLabel.getFont());
Field descentField = calibriMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(calibriMetrics, tahomaMetrics.getDescent());
Field ascentField = calibriMetrics.getClass().getDeclaredField("ascent");
ascentField.setAccessible(true);
ascentField.set(calibriMetrics, tahomaMetrics.getAscent());
Field leadingField = calibriMetrics.getClass().getDeclaredField("leading");
leadingField.setAccessible(true);
leadingField.set(calibriMetrics, tahomaMetrics.getLeading());
} catch (Exception e) {
e.printStackTrace();
}
}
现在,用 copyTahomaFontMetricsTo(withHtml);
来称呼它,而不关心它是 withHtml
标签还是 withoutHtml
,因为 它们都具有相同的字体。
结果(框架标题中的字体大小):
即使旁边还有其他 text-based 个组件:
如您所见,它成功了!再加上布局对齐没有搞砸。
看起来很完美,其实不然。
同样,如前所述,对于每种字体(family
、size
和 style
的组合),都有一个 FontMetrics
实例。将其中一个标签的字体更改为 Font.BOLD
将阻止我们获得完美对齐。可能错过一个(或两个)像素。另外,对于 Bold
,我们还必须 copyTahomaFontMetricsTo
:
copyTahomaFontMetricsTo(withoutBoldFont);
copyTahomaFontMetricsTo(withBoldFont);
和结果(框架标题上的字体大小):
仔细看:
有一个像素的差异。但我想我会接受它,因为这比 Swing's/Windows 默认 Calibri-HTML 行为好(方式):
完整示例:
public class FontExample extends JFrame {
private static final Font FONT = new Font("Calibri", Font.PLAIN, 20);
public FontExample() {
super("Font: " + FONT.getSize());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel withoutHtml = new JLabel("hello Whosebug");
withoutHtml.setBorder(BorderFactory.createLineBorder(Color.GREEN));
withoutHtml.setFont(FONT.deriveFont(Font.BOLD));
add(withoutHtml);
JLabel withHtml = new JLabel("<html>hello Whosebug");
withHtml.setBorder(BorderFactory.createLineBorder(Color.RED));
withHtml.setFont(FONT);
copyTahomaFontMetricsTo(withoutHtml);
copyTahomaFontMetricsTo(withHtml);
add(withHtml);
setLocationByPlatform(true);
pack();
}
private static void copyTahomaFontMetricsTo(JLabel label) {
try {
FontMetrics calibriMetrics = label.getFontMetrics(label.getFont());
// Create a dummy JLabel with tahoma font, to obtain tahoma font metrics
JLabel dummyTahomaLabel = new JLabel();
dummyTahomaLabel.setFont(new Font("Tahoma", label.getFont().getStyle(), label.getFont().getSize()));
FontMetrics tahomaMetrics = dummyTahomaLabel.getFontMetrics(dummyTahomaLabel.getFont());
Field descentField = calibriMetrics.getClass().getDeclaredField("descent");
descentField.setAccessible(true);
descentField.set(calibriMetrics, tahomaMetrics.getDescent());
Field ascentField = calibriMetrics.getClass().getDeclaredField("ascent");
ascentField.setAccessible(true);
ascentField.set(calibriMetrics, tahomaMetrics.getAscent());
Field leadingField = calibriMetrics.getClass().getDeclaredField("leading");
leadingField.setAccessible(true);
leadingField.set(calibriMetrics, tahomaMetrics.getLeading());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new FontExample().setVisible(true);
});
}
}