0

I'm attempting to add some high-range unicode characters to a JLabel inside of a JFrame, but they only show up as boxes despite using a known supported font. However, when I print these same characters to the Eclipse console, they show up just fine. Here is my code, with "frame" being my JFrame and "textField1" being my JLabel. The Monaco font is the same font that the Eclipse console uses, and is know to support this unicode character:

JFrame frame = new JFrame();
JLabel textField1 = new JLabel();
frame.add(textField1);
frame.setFocusable(true);
frame.setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
frame.setPreferredSize(new Dimension(1000, 500));
frame.requestFocusInWindow();
frame.textField1.setFont(new Font("Monaco", Font.PLAIN, 11 ));
frame.textField1.setText("\uD83C\uDF2D"); 
frame.pack();
frame.setVisible(true);

I've tried setting the JLabel to many different fonts, but all that changes is the relative shape of the "missing character" box. However, if I print this:

System.out.println("\uD83C\uDF2D");

the character prints as expected in the console. Is there some encoding issue that prevents these symbols from working in Swing?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
zooksman
  • 13
  • 4
  • 2
    The most common cause is the font doesn't support the display of the characters – MadProgrammer Oct 11 '17 at 23:44
  • @MadProgrammer Yes but as I stated I am 100% sure that this font supports the character, I looked it up plus it is the same font as the console as I said which displays it perfectly. I have also tried multiple other fonts known to support this character to no avail. – zooksman Oct 11 '17 at 23:55
  • 1
    I don't believe the Monaco font has the character (['HOT DOG' (U+1F32D)](http://www.fileformat.info/info/unicode/char/1f32d/index.htm)). It's more likely that the console is auto-switching to another font to show special characters. If you paste that character into this page, you'll see it doesn't work: https://www.myfonts.com/fonts/apple/monaco/ – Andreas Oct 12 '17 at 00:14
  • Is there any way to identify what font it is switching to? I don't have any way of knowing which fonts on this system actually support it. – zooksman Oct 12 '17 at 00:37
  • I agree with @Andreas And based on it, added my answer. – Optional Oct 12 '17 at 05:10

2 Answers2

3

First thing first.

1) \uD83C\uDF2D is not supported on Moncaco font.

2) You can check font that supports this character at fileformat

3) Supported font that seems to work for this character, listed there are: LastResport, Symbola and Unifont Upper. See link

Now how do you support it in Java? Download the font, set it to label and use it as shown below.

import java.awt.Dimension;
import java.awt.Font;
import java.io.File;
import java.net.URI;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

public class FrameMain1 {

    public static void main(String[] args) throws Exception {

        File fontFile = new File(new URI("file:///D:/tmp/Symbola.ttf"));
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
        font = font.deriveFont(Font.PLAIN, 24f);
        JFrame frame = new JFrame();
        JLabel label1 = new JLabel("\uD83C\uDF2D");
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
        frame.add(label1);
        frame.setFocusable(true);
        //frame.setPreferredSize(new Dimension(1000, 500));
        frame.requestFocusInWindow();
        label1.setFont(font);
        frame.add(label1);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

}

See the image

Optional
  • 4,387
  • 4
  • 27
  • 45
3

The Font.canDisplayUpTo(String) method is your friend here. This is how it might be used to create a combo of the fonts that support the text.

        String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().
                getAvailableFontFamilyNames();
        System.out.println(fonts.length + " font families installed");
        Vector<String> supportedFonts = new Vector<>();
        for (String fontName : fonts) {
            Font f = new Font(fontName, Font.PLAIN, 1);
            if (f.canDisplayUpTo(text)<0) {
                System.out.println(fontName);
                supportedFonts.add(fontName);
            }
        }
        fontComboBox = new JComboBox(supportedFonts);

This shows the number of fonts installed on this computer, followed by a listing of the fonts that will display the text (character for a hot-dog).

225 font families installed
Segoe UI Emoji
Segoe UI Symbol

This is the source code that produces the above output, as well as displaying a GUI that allows the user to choose between all the fonts that support the given Unicode character(s):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.Vector;

public class FontCheck {

    private JComponent ui = null;

    private final String text = "\uD83C\uDF2D"; 
    private JComboBox fontComboBox;
    private JTextField outputField = new JTextField(text, 5);

    FontCheck() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4,4));

        ui.add(outputField);
        ui.add(getToolBar(), BorderLayout.PAGE_START);

        refreshFont();
    }

    private JToolBar getToolBar() {
        JToolBar tb = new JToolBar();
        tb.setLayout(new FlowLayout());

        String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().
                getAvailableFontFamilyNames();
        System.out.println(fonts.length + " font families installed");
        Vector<String> supportedFonts = new Vector<>();
        for (String fontName : fonts) {
            Font f = new Font(fontName, Font.PLAIN, 1);
            if (f.canDisplayUpTo(text)<0) {
                System.out.println(fontName);
                supportedFonts.add(fontName);
            }
        }
        fontComboBox = new JComboBox(supportedFonts);
        ActionListener refreshListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                refreshFont();
            }
        };
        fontComboBox.addActionListener(refreshListener);

        tb.add(fontComboBox);
        return tb;
    }

    private void refreshFont() {
        String fontName = fontComboBox.getSelectedItem().toString();
        Font f = new Font(fontName, Font.PLAIN, 60);
        outputField.setFont(f);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                FontCheck o = new FontCheck();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • just in case it matters if I do not have those fon't installed, I get NPE: EventQueue-0" java.lang.NullPointerException at test.FontCheck.refreshFont(FontCheck.java:70) at test.FontCheck.initUI(FontCheck.java:37) at test.FontCheck.(FontCheck.java:23)` – Optional Oct 12 '17 at 10:36
  • 1
    *"just in case it matters if I do not have those fon't installed"* It matters that you understand the code, which would **not include uninstalled fonts** and will **not throw an NPE** with the source exactly as shown above. – Andrew Thompson Oct 12 '17 at 15:32
  • And how would one install a new unsupported font? Wasn't that important as well @andrew-thompson ? Nevertheless, a bit of application can solve OP's problem as well. – Optional Oct 12 '17 at 17:04
  • @Optional *"And how would one install a new unsupported font?"* See [this answer](https://stackoverflow.com/questions/13717481/setting-custom-font/13718134#13718134). *"Wasn't that important as well ..?"* Whether it's important or not is not the question. This question was about whether the failure was an encoding issue. – Andrew Thompson Oct 13 '17 at 00:32
  • 1
    Thanks, this is super helpful and fixed the problem. – zooksman Oct 13 '17 at 15:11