Java Swing中macOS系统字体缺失字形(如emoji)的fallback问题
在macOS 15(Sequoia)+ OpenJDK 23的Swing中使用.AppleSystemUIFont时的Emoji回退显示问题
我在搭载macOS 15(Sequoia)的Mac设备上使用OpenJDK 23,希望在Swing GUI中使用macOS系统字体。通过字体名称.AppleSystemUIFont引用时,字体可正常应用,但和默认字体Lucida Grande相比,Emoji等符号的回退机制失效,不支持的字形完全无法显示。
我尝试过多种方法均无效,推测macOS的回退/合成机制由原生代码处理,想请教是否有办法将.AppleSystemUIFont定义为主要字体,同时保留正常的字形回退功能?
Swing中列出的可用Apple字体包括:
- .AppleSystemUIFont
- Apple Braille
- Apple Chancery
- Apple Color Emoji
- Apple SD Gothic Neo
- Apple Symbols
- AppleGothic
- AppleMyungjo
- SF Mono
有趣的是,当指定SF Mono作为字体名称时,回退机制可正常工作,但这并非我需要的字体。
示例代码
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 😊"); frame.add(label); frame.setSize(new Dimension(300, 80)); frame.setLocationRelativeTo(null); frame.setVisible(true); }); } }
渲染效果对比
使用默认字体渲染效果
使用.AppleSystemUIFont渲染效果
使用等宽默认字体渲染效果
使用SF Mono字体渲染效果
2025-03-14 更新
使用JetBrains Runtime 21.0.6运行相同代码时,.AppleSystemUIFont可正常显示字体及Emoji。这似乎是JDK原生代码中的问题,而JetBrains团队已修复该问题。

内容的提问来源于stack exchange,提问作者meyertee
相关产品推荐
相关产品推荐

