当字体与系统字体冲突时,Java JLabel HTML显示乱码

时间:2015-11-28 10:43:02

标签: java html swing encoding jlabel

更新 - 问题现在以丑陋的方式解决了 - 但必须有一个正确的方法来做到这一点吗?

当字体名称与系统上已安装的字体名称冲突时,我在使用自定义字体呈现文本时遇到问题,在JLabel 中以HTML格式呈现

系统字体采用不同的格式(otf vs ttf),不出所料,文字是乱码。

GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont的调用返回false以显示无法注册的字体。所以我想问题是,有没有办法在没有注册的情况下使用这种字体,或者在注册之前重命名它?

我现在通过编辑ttf文件并修改字体名称来解决我的问题,使冲突极不可能,但我猜测必须有一种正确的方法来处理这种情况。

package test;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
class MyComponent extends JPanel {
    Font font; String text;
    public MyComponent(Font f) {font=f;}
    public void initSwing()
    {
        final String labelcontents = "<html><center>foo</center></html>";
        System.out.println(labelcontents);
        JLabel text = new JLabel(labelcontents);
        text.setFont(font);
        add(text,BorderLayout.CENTER);
    }
}

@SuppressWarnings("serial")
public class TestApplet extends JApplet {
        public void init()
        {
            Font mainFont = null;
            InputStream is = getClass().getResourceAsStream("fonts/Exo-Bold.ttf");
            try {
                mainFont = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(24f);
                System.out.println(mainFont.getName());
                boolean registered=GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(mainFont);
                System.out.println("registered "+registered);
            } catch (FontFormatException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            final Container fframe = (JComponent)(getContentPane());
            final MyComponent component = new MyComponent(mainFont);

            Thread t = new Thread(new Runnable() {
                public void run() { try {

                    SwingUtilities.invokeAndWait(new Runnable() {public void run() {
                        fframe.add(component);
                        component.initSwing();
                        fframe.revalidate();
                        fframe.repaint();
                    }});

                } catch (Exception e) {
                    e.printStackTrace();
                } }
            });
            t.start();
        }
}

2 个答案:

答案 0 :(得分:1)

也许该文本包含带有charset等的HTML命令。

String text1 = "<html><body>"
    + text.replace("&", "&amp;")
          .replace("<", "&lt;")
          .replace(">", "&gt;");
    + "</body></html>";

答案 1 :(得分:1)

很奇怪。当我在笔记本电脑上运行您的示例小程序时,输出似乎很好:

Screenshot with perfectly nice spelled "foo"

我已将此zip file与“Exo-Bold.ttf”文件一起使用,并在Windows 8.1上使用Java 8(Oracle JDK的1.8.0_65版本)。

这是我运行的代码的改编版本:

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

@SuppressWarnings("serial")
class MyComponent extends JPanel {
    Font font; String text;
    public MyComponent(Font f) {font=f;}
    public void initSwing()
    {
        final String labelcontents = "<html><center>foo</center></html>";
        System.out.println(labelcontents);
        JLabel text = new JLabel(labelcontents);
        text.setFont(font);
        add(text,BorderLayout.CENTER);
    }
}

@SuppressWarnings("serial")
public class TestApplet extends JApplet {
    public void init()
    {
        Font mainFont = null;

        try {
            //InputStream is = getClass().getResourceAsStream("fonts/Exo-Bold.ttf");
            InputStream is = new FileInputStream("C:/Freek/[...]/Exo-Bold.ttf");
            mainFont = Font.createFont(Font.TRUETYPE_FONT, is)
                           .deriveFont(Font.BOLD, 24f);
            is.close();
            System.out.println(mainFont.getName());
            boolean result = GraphicsEnvironment.getLocalGraphicsEnvironment()
                                                .registerFont(mainFont);
            System.out.println("Result registerFont: " + result);
        } catch (FontFormatException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        final Container fframe = (JComponent)(getContentPane());
        final MyComponent component = new MyComponent(mainFont);

        Thread t = new Thread(new Runnable() {
            public void run() { try {

                SwingUtilities.invokeAndWait(new Runnable() {public void run() {
                    fframe.add(component);
                    component.initSwing();
                    fframe.revalidate();
                    fframe.repaint();
                }});

            } catch (Exception e) {
                e.printStackTrace();
            } }
        });
        t.start();
    }
}