3

I have here a simple, complete, self-contained, pure-Java program that displays a frame containing a button with a Unicode emoji character as its text. This program runs correctly and displays the emoji on Windows, but not on Mac OS (Catalina, AdoptOpenJDK15).

side by side frames in Windows/Mac

Here is the source code; filename is EmojiTest.java:

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

public class EmojiTest {

  public static void main(String[] args) {
    // listFonts();  // Uncomment if you want to see all registered fonts.
    JFrame frame = new JFrame();
    frame.setTitle("Emoji Demo: " + System.getProperty("os.name"));
    frame.setSize(400, 300);

    JButton button = new JButton();
    String emoji = "\ud83d\udc36";  // dog face
    button.setText(emoji);
    button.setFont(getFont(emoji));
    JPanel holder = new JPanel();  // Let button be natural size
    holder.add(button);

    frame.getContentPane().add(holder);
    frame.setVisible(true);
  }

  static Font getFont(String emoji) {
    String os = System.getProperty("os.name");
    String fontFamily = os.equals("Mac OS X") ? "Apple Color Emoji" : "Segoe UI Emoji";
    Font font = new Font(fontFamily, Font.PLAIN, 20);
    System.out.println("Font: " + font);
    System.out.println("can display result: " + font.canDisplayUpTo(emoji));
    return font;
  }

  static void listFonts() {
    String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getAvailableFontFamilyNames();
    for (int i = 0; i < fonts.length; i++) {
      System.out.println(fonts[i]);
    }
  }
}

A few things to observe here:

  • The getFont() helper method prints out whether the font thinks it can display the text. On MacOS, it always prints -1, meaning it thinks it can display the text.

  • All 279 fonts on my Apple system claim (via canDisplayUpTo) that they can display it, but they fail to display it. Yes, I tested all of them visually, and no, none worked.

  • As you can see from the picture, this program works correctly on Windows. So the code is "correct", in the sense that it should work on Macs.

I'm fairly convinced that this is a JDK bug. However, if you debug the EmojiTest program in IntelliJ, it actually shows you in the debug pane that the text is in fact the correct emoji:

java debugger shows the emoji

So IntelliJ, a Java program running on Mac OS Catalina, is able to render the emoji correctly in its font—admittedly, not in a JButton. But I have also tried rendering emoji in JTextPanes and other Swing widgets on MacOS, to no avail.

This question has been asked several times over the past few years, often indirectly, but the answer is always "You need to make sure your font can display the emoji".

I think this program pretty clearly demonstrates that the font being able to display the emoji is not the issue. The Apple Color Emoji font can absolutely display emoji, including this one. It just doesn't seem to be able to do it in Java.

Here's my question: How can I modify this EmojiTest.java program to show the emoji on MacOS?

Stevey
  • 2,822
  • 1
  • 23
  • 30
  • `os.equals("Mac OS X")` ← Are you sure that‘s the exact value in the os.name system property? Consider using `os.contains("Mac")` instead. – VGR Nov 07 '20 at 23:15
  • Seems strange that all 279 Fonts support this. Check out: https://stackoverflow.com/a/29028982/131872. The code there indicates that only 7 fonts on my Windows system can display those characters. Try that test program to see if you get the same results. – camickr Nov 07 '20 at 23:22
  • Yes, that's the exact os name property on my system, @VGR – Stevey Nov 09 '20 at 00:24
  • @camickr I ran that program on my system and all but 4 of the fonts could display the characters. The 4 that couldn't were wingdings/ornaments fonts. Scrolling through the list of fonts, they actually all did show the Croation characters. – Stevey Nov 09 '20 at 00:30
  • The point was to change the "Croation characters" to your Uincode characters to see the results. Do you still have all 279 fonts or a smaller subset? I find it hard to believe that all 279 Fonts on your system will display your Unicode characters since only 7 Windows fonts will display those Unicode characters. So I'm questioning if your logic to determine which font to use is flawed. Or maybe the canDisplayUpto(...) method isn't working? – camickr Nov 09 '20 at 00:54
  • Yes @camickr -- I thought it was clearer from my write-up, but all 279 fonts claim they can display all characters, and NONE of them can _actually_ display the characters. Which implies that canDisplayUpTo is broken on AdoptOpenJDK15 for the Mac -- at least, I think that's the most likely explanation. – Stevey Nov 10 '20 at 09:23

0 Answers0