Ryan N
Ryan N

Reputation: 669

JLabel html text ignores setFont

I've just started porting my Swing app from OS X to Windows and things are painful with JLabels.

I've noticed that the font specified to setFont is ignored if the label's text is HTML (this doesn't happen on the Mac). The HTML formatting is EXTREMELY useful for readability on complicated displays.

Under normal circumstances I'd specify the font in an HTML tag, but the font I'm using is loaded at runtime using Font.createFont with a ttf out of the JAR. I tried using the loaded font's name in the font tag, but that didn't work.

Is there any way I can use a loaded awt.Font with an html-ified JLabel on Windows?

Here's an example. I can't share my application's font, but I just ran it with this one (a pure TTF) and the same behavior happens:

http://www.dafont.com/sophomore-yearbook.font

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

public class LabelTestFrame extends JFrame {

        public LabelTestFrame() throws Exception {
                boolean useHtml = true;
                String fontPath = "C:\\test\\test_font.ttf";
                JLabel testLabel = new JLabel();
                Font testFont = Font.createFont(Font.TRUETYPE_FONT, new File(fontPath)).deriveFont(18f);
                testLabel.setFont(testFont);
                if (useHtml) testLabel.setText("<html>Some HTML'd text</html>");
                else testLabel.setText("Some plaintext");
                getContentPane().add(testLabel);
                setSize(300,300);
        }

        public static void main(String[] args) {
                SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                                try {new LabelTestFrame().setVisible(true);}
                                catch (Exception e) {e.printStackTrace();}
                        }
                });
        }

}

EDIT: interestingly enough, if I use one of the ttf's from the JRE's lib/fonts folder (in this case one of the Lucida fonts here renamed to test_java.ttf) this snippet produces identical results with the boolean on and off.

public LabelTestFrame() throws Exception {
    boolean useHtml = false;
    String fontPath = "C:\\test\\test_java.ttf";
    JLabel testLabel = new JLabel();
    Font testFont = Font.createFont(Font.TRUETYPE_FONT, new File(fontPath)).deriveFont(18f);
    testLabel.setFont(testFont);
    if (useHtml) testLabel.setText("<html><b>Some HTML'd text</b></html>");
    else testLabel.setText("Some plaintext");
    getContentPane().add(testLabel);
    setSize(300,300);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {new LabelTestFrame().setVisible(true);}
            catch (Exception e) {e.printStackTrace();}
        }
    });
}

EDIT 2: The method described here for setting the default JLabel font has exactly the same problem (plaintext shows fine, html'd text doesn't): Changing default JLabel font

EDIT 3: I've noticed that even random fonts from dafont will work if they're installed on the system (even with this exact code, where I'm loaded a copy of the [now installed] ttf from a file).

Upvotes: 11

Views: 3772

Answers (2)

Ryan N
Ryan N

Reputation: 669

registerFont()

I found this little gem while Googling about if I could copy a .ttf into the JRE at runtime. It does exactly what it's supposed to. If you use Font.createFont to load a font at runtime, just do:

GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(myCreatedFont)

to register it with the JRE.

This allows the font to show up in HTML'd text as well as plaintext on Windows!

Upvotes: 15

trashgod
trashgod

Reputation: 205885

For reference, here's what is seen on Mac OS X.

enter image description here

By comparison, here's the display on Ubuntu 10, OpenJDK 6.

enter image description here

import java.awt.Font;
import java.awt.GridLayout;
import java.io.File;
import javax.swing.*;

public class LabelTestFrame extends JFrame {

    public LabelTestFrame() throws Exception {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new GridLayout(0, 1));
        String fontPath = "SophomoreYearbook.ttf";
        Font testFont = Font.createFont(
            Font.TRUETYPE_FONT, new File(fontPath)).deriveFont(18f);
        JLabel label1 = new JLabel("<html>Some HTML'd text</html>");
        label1.setFont(testFont);
        this.add(label1);
        JLabel label2 = new JLabel("Some plaintext");
        this.add(label2);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new LabelTestFrame().setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Upvotes: 4

Related Questions