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).
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:
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?