JLabel中的自定义字体被截断

时间:2014-05-23 17:51:32

标签: java swing fonts 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);
    }
}

应该出现

Showing full font

pack()

之后出现

As it first appears

更大的观点指出了i& Ĵ

As it first appears

感谢任何帮助!

2 个答案:

答案 0 :(得分:4)

这是一个观察。 (底部的代码)

enter image description here

我得到了字体的字体指标,并绘制了字体的重音和基线所在的行。您可以清楚地看到i中的点高于重音线的上方,这是截止点。使用指标计算标签的首选大小。因此,基于此,首选大小将切断部分ij的底部不会被切断,因为考虑了下降线。

至于消息被切断的原因,可能有一些原因。在原始代码中,没有遇到问题,可能是因为字体太小,而且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);
    }
}

答案 1 :(得分:1)

我安装了字体,并以Documentation方式使用setFont方法:

import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());//Un-commenting causes text to be cut off
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel(
                "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
        label.setFont(new Font("BPDiet", Font.BOLD, 15));
        frame.add(label);
        frame.setSize(800, 500);
        frame.setVisible(true);
    }
}

我删除了您的方法并以更简单的方式设置了字体,如果您仍然需要该方法,那么只需回复即可尝试添加或解决问题。

尝试并告诉我它是否有帮助:)