I'm using OpenJDK 23 on a Mac with macOS 15 (Sequoia) and I'd like to use the macOS system font in my Swing GUI.
I reference the system font with the font name .AppleSystemUIFont
and the font is applied correctly, but the fallback behavior for symbols like emojis seems to be lost as opposed to the default font Lucida Grande
. The unsupported glyphs simply aren't displayed, see attached screenshots and example code below.
I've tried various hacks, I'm not aware of any other mechanism as the one in the code example and nothing works. It seems like the fallback/composite behavior for macOS is handled in native code, is there any way to define .AppleSystemUIFont
as the primary font rather than Lucida Grande
?
The following Apple-fonts are listed as available fonts in Swing: .AppleSystemUIFont, Apple Braille, Apple Chancery, Apple Color Emoji, Apple SD Gothic Neo, Apple Symbols, AppleGothic, AppleMyungjo, SF Mono
.
Interestingly, when I specify SF Mono
as the font name in the example below, the fallback works with the SF Mono font (but that's not the font I want of course).
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.Map;
public class MacFontFallback {
private static void setupMacOsFont() {
Font defaultFont = UIManager.getDefaults().getFont("Label.font");
Map<TextAttribute, Object> normalAttributes = Map.of(TextAttribute.FAMILY, ".AppleSystemUIFont");
Font derivedFont = defaultFont.deriveFont(normalAttributes);
FontUIResource fontUIResource = new FontUIResource(derivedFont);
UIManager.put("defaultFont", fontUIResource);
UIManager.put("Label.font", fontUIResource);
}
public static void main(String[] args) {
setupMacOsFont();
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Mac Font");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Hello