11package com .laker .postman .util ;
22
3- import com .formdev .flatlaf .util .SystemInfo ;
4-
53import javax .swing .*;
64import java .awt .*;
7- import java .util .Arrays ;
8- import java .util .HashSet ;
9- import java .util .Set ;
105
116/**
12- * 字体工具类,统一根据操作系统选择合适的字体。
7+ * 字体工具类,提供系统默认字体,保留完整的字体降级链以支持 emoji 等特殊字符
138 */
149public class EasyPostManFontUtil {
15- public static final int DEFAULT_FONT_SIZE = 12 ;
16-
17- // 默认字体名称常量
18- private static final String DEFAULT_FONT_NAME = "SansSerif" ;
19-
20- // 缓存首选字体族,避免重复查找
21- private static String cachedPreferredFontFamily = null ;
22-
2310 // 私有构造函数,防止实例化工具类
2411 private EasyPostManFontUtil () {
2512 throw new UnsupportedOperationException ("Utility class cannot be instantiated" );
2613 }
2714
2815 /**
29- * 获取默认字体,保留字体降级链以支持 emoji 等特殊字符
16+ * 获取默认字体,从 UIManager 派生以保留降级链,支持 emoji 等特殊字符
3017 *
3118 * @param style 字体样式 (Font.PLAIN, Font.BOLD, Font.ITALIC)
3219 * @param size 字体大小
33- * @return Font 对象,使用首选字体族
20+ * @return Font 对象,从系统默认字体派生
3421 */
3522 public static Font getDefaultFont (int style , int size ) {
36- String fontFamily = getCachedPreferredFontFamily ();
37- return new Font (fontFamily , style , size );
38- }
39-
40- /**
41- * 获取缓存的首选字体族,如果未缓存则查找并缓存
42- *
43- * @return 首选字体族名称
44- */
45- private static String getCachedPreferredFontFamily () {
46- if (cachedPreferredFontFamily == null ) {
47- cachedPreferredFontFamily = getPreferredFontFamily ();
48- if (cachedPreferredFontFamily == null ) {
49- cachedPreferredFontFamily = DEFAULT_FONT_NAME ;
50- }
51- }
52- return cachedPreferredFontFamily ;
53- }
54-
55- /**
56- * 设置字体缩放和首选字体族,保留字体降级链,支持 emoji 等特殊字符
57- * 这种方式不会破坏系统的字体 fallback 机制
58- */
59- public static void setupFontScaling () {
60-
61- // 根据操作系统设置首选字体族,而不是直接替换字体
62- String preferredFontFamily = getPreferredFontFamily ();
63-
64- if (preferredFontFamily != null && !DEFAULT_FONT_NAME .equals (preferredFontFamily )) {
65- // 仅设置默认字体族,让系统自动处理降级
66- UIManager .put ("defaultFont" , new Font (preferredFontFamily , Font .PLAIN , DEFAULT_FONT_SIZE ));
67-
68- // 针对特定组件设置字体族(而非完整字体),保留降级链
69- Font baseFont = new Font (preferredFontFamily , Font .PLAIN , DEFAULT_FONT_SIZE );
70-
71- // 只设置关键的 UI 组件字体,使用 deriveFont 保留字体属性
72- UIManager .put ("Label.font" , baseFont );
73- UIManager .put ("Button.font" , baseFont );
74- UIManager .put ("TextField.font" , baseFont );
75- UIManager .put ("TextArea.font" , baseFont );
76- UIManager .put ("ComboBox.font" , baseFont );
77- UIManager .put ("Table.font" , baseFont );
78- UIManager .put ("Tree.font" , baseFont );
79- UIManager .put ("List.font" , baseFont );
80- UIManager .put ("Menu.font" , baseFont );
81- UIManager .put ("MenuItem.font" , baseFont );
82- UIManager .put ("PopupMenu.font" , baseFont );
83- UIManager .put ("ToolTip.font" , baseFont );
84- UIManager .put ("TabbedPane.font" , baseFont );
85- }
86- }
87-
88- /**
89- * 获取操作系统首选字体族名称
90- *
91- * @return 首选字体族名称,如果没有找到则返回 null
92- */
93- private static String getPreferredFontFamily () {
94- if (SystemInfo .isMacOS ) {
95- // macOS 优先使用 PingFang SC
96- String [] macFonts = {"PingFang SC" , ".AppleSystemUIFont" , "Hiragino Sans GB" };
97- return findAvailableFontFamily (macFonts );
98- } else if (SystemInfo .isWindows ) {
99- // Windows 优先使用 Microsoft YaHei UI 或 Segoe UI
100- String [] winFonts = {"Microsoft YaHei UI" , "微软雅黑" , "Segoe UI" };
101- return findAvailableFontFamily (winFonts );
102- } else if (SystemInfo .isLinux ) {
103- // Linux 优先使用 Noto Sans 或 WenQuanYi
104- String [] linuxFonts = {"Noto Sans CJK SC" , "WenQuanYi Micro Hei" , "DejaVu Sans" };
105- return findAvailableFontFamily (linuxFonts );
106- }
107- return null ;
108- }
109-
110- /**
111- * 从字体列表中查找第一个可用的字体族
112- *
113- * @param fontNames 字体名称数组
114- * @return 第一个可用的字体族名称,如果都不可用则返回 null
115- */
116- private static String findAvailableFontFamily (String [] fontNames ) {
117- if (fontNames == null ) {
118- return null ;
119- }
120-
121- GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment ();
122- String [] availableFonts = ge .getAvailableFontFamilyNames ();
123- Set <String > availableFontSet = new HashSet <>(Arrays .asList (availableFonts ));
124-
125- for (String fontName : fontNames ) {
126- if (fontName != null && availableFontSet .contains (fontName )) {
127- return fontName ;
128- }
23+ // 从 UIManager 获取默认字体,使用 deriveFont 派生,保留降级链
24+ Font baseFont = UIManager .getFont ("Label.font" );
25+ if (baseFont == null ) {
26+ // 如果 UIManager 中没有,使用系统默认字体
27+ baseFont = new JLabel ().getFont ();
12928 }
130- return null ;
29+ // 使用 deriveFont 派生新字体,保留原字体的所有属性和降级链
30+ return baseFont .deriveFont (style , (float ) size );
13131 }
13232}
0 commit comments