JLabel 中的自定义字体被截断

Chr*_*ith 2 java fonts swing jlabel flowlayout

我有一个 JLabel,我已为其设置了自定义字体“BP Diet”。如果我将其添加到 JFrame,文本显示正常,但一旦我将 JFrame 的布局更改为 FlowLayout,文本的顶部就会被切断。当您将 JLabel 添加到 JPanel 并将其添加到 JFrame 时,也会出现同样的问题。我可以在http://www.hichris.com/more/files/BPdiet.otf找到该字体

下面是代码:

import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;

public class FontSizeTest {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel(
                "AaBbCcDdEeFfGgHhIiJjKk");
        label.setFont(createFont());
        frame.add(label);
        frame.pack();
        frame.setMinimumSize(frame.getMinimumSize());
        frame.setVisible(true);
    }

    static Font createFont() {
        Font customFont = null;
        try {
            URL url = new URL("http://www.hichris.com/more/files/BPdiet.otf");
            InputStream is = url.openStream();
            customFont = Font.createFont(Font.TRUETYPE_FONT, is);
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(customFont);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return customFont.deriveFont(25f);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如它应该出现的那样

显示完整字体

正如之后出现的那样pack()

正如它第一次出现时那样

更大的视角指出 i 和 j 上面的点

正如它第一次出现时那样

任何帮助表示赞赏!

Pau*_*tha 5

这是一个观察结果。(代码在底部)

在此输入图像描述

我获取了字体的字体规格,并在字体的重音线和基线所在的位置画了一条线。您可以清楚地看到,图中的点i位于强调线上方,即截止点。标签的首选大小是使用指标计算的。因此,基于此,首选尺寸将切除部分i. 但底部j不会被切断,因为考虑了下降线。

至于消息为何被切断,可能有几个原因。在您的原始代码中,没有遇到问题,可能是因为字体太小,并且 FlowLayout 有默认的 5px 间隙。在新的示例中,它被切断,pack()因为默认的 BorderLayout没有默认的间隙。

您可以解决这个问题,就像 AndrewThompson 提到的那样,只需使用EmptyBorder, 或指定布局的间隙。需要考虑的事情是FlowLayout尊重组件的首选大小,因此标签将设置为其首选大小,同时考虑字体规格。将BorderLayout考虑首选尺寸,对于标签,将拉伸标签以适合布局位置并使文本垂直居中

import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;

public class FontSizeTest {
    static String message = "AaBbHhIiJjKk";

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createFontTestPanel());
        frame.pack();
        frame.setMinimumSize(frame.getMinimumSize());
        frame.setVisible(true);
    }

    static Font font = createFont();

    static JPanel createFontTestPanel() {
        return new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setFont(font);
                FontMetrics fm = g.getFontMetrics();
                int stringHeight = fm.getAscent();
                int stringWidth = fm.stringWidth(message);

                int beginString = getWidth()/2 - stringWidth/2;
                int baseString = getHeight()/2 + stringHeight/2;

                // draw accent line
                g.drawLine(0, baseString - stringHeight, getWidth(), baseString - stringHeight);
                // draw base line
                g.drawLine(0, baseString, getWidth(), baseString);
                // draw message
                g.drawString(message, beginString, baseString);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(500, 150);
            }
        };
    }

    static Font createFont() {
        Font customFont = null;
        try {
            URL url = new URL("http://www.hichris.com/more/files/BPdiet.otf");
            InputStream is = url.openStream();
            customFont = Font.createFont(Font.TRUETYPE_FONT, is);
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(customFont);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return customFont.deriveFont(50f);
    }
}
Run Code Online (Sandbox Code Playgroud)