Java Swing多语言显示异常:Windows下非拉丁文字符显示为方块
Swing多语言字符在Windows 10显示方块的解决方案
问题背景
开发的多语言Swing应用中,孟加拉语、泰卢固语、尼泊尔语等非拉丁语言字符在Windows 10的Swing组件中显示为方块,但Linux Ubuntu系统显示正常,Windows控制台输出也正常。
示例代码
public class SwingLang { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(230,500); JPanel panel = new JPanel(); String[] x = new String[7]; // 对应英文:"Checking your configuration and account" x[0] = "ব্যবস্থা এবং একাউন্ট দেখা"; //孟加拉语 x[1] = "తయారీ మరియు ఖాతా తనిఖీ"; //泰卢固语 x[2] = "तयारी र खाता जाँच"; //尼泊尔语 x[3] = "සූදානම් වීම සහ ගිණුම පරීක්\u200Dෂාව"; //僧伽罗语 x[4] = "तैयारी और खाता जांच"; //印地语 x[5] = "தயாரிப்பு மற்றும் கணக்கு சரிபார்ப்பு"; //泰米尔语 x[6] = "การเตรียมและตรวจสอบบัญชี"; //泰语 for (int i = 0; i < x.length; i++) { JLabel label = new JLabel(x[i]); System.out.println(x[i]); panel.add(label); } frame.add(panel); frame.setVisible(true); } }
已尝试操作
- 传入Unicode字符串,控制台输出正常但Swing仍显示方块
- 通过Font类替换字体,未解决问题
- 更换Open JDK 17到21版本(高于21的版本与Lombok不兼容,已排除)
解决方案
代码层面:自动匹配支持目标字符的字体
Swing默认字体通常不覆盖所有复杂脚本,可通过动态检测系统中能渲染对应字符的字体来解决:
import java.awt.Font; import java.awt.GraphicsEnvironment; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class SwingLang { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(230, 500); JPanel panel = new JPanel(); String[] texts = new String[7]; texts[0] = "ব্যবস্থা এবং একাউন্ট দেখা"; //孟加拉语 texts[1] = "తయారీ మరియు ఖాతా తనిఖీ"; //泰卢固语 texts[2] = "तयारी र खाता जाँच"; //尼泊尔语 texts[3] = "සූදානම් වීම සහ ගිණුම පරීක්\u200Dෂාව"; //僧伽罗语 texts[4] = "तैयारी और खाता जांच"; //印地语 texts[5] = "தயாரிப்பு மற்றும் கணக்கு சரிபார்ப்பு"; //泰米尔语 texts[6] = "การเตรียมและตรวจสอบบัญชี"; //泰语 // 获取系统所有可用字体 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); Font[] allFonts = ge.getAllFonts(); for (String text : texts) { JLabel label = new JLabel(text); // 遍历字体,找到能完整渲染当前文本的字体 for (Font font : allFonts) { if (font.canDisplayUpTo(text) == -1) { label.setFont(font.deriveFont(12f)); break; } } panel.add(label); System.out.println(text); } frame.add(panel); frame.setVisible(true); } }
代码层面:直接指定多语言通用字体
如果不需要自动检测,可直接指定Windows系统中支持复杂脚本的字体,比如Segoe UI(Windows 10原生支持多语言):
// 创建JLabel后添加此行代码 label.setFont(new Font("Segoe UI", Font.PLAIN, 12));
启动参数层面:强制指定默认字体或启用渲染优化
通过JVM启动参数全局配置Swing字体,无需修改代码:
- 指定默认UI字体:
java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel -Dswing.plaf.metal.controlFont="Segoe UI" -Dswing.plaf.metal.userFont="Segoe UI" SwingLang
- 启用硬件加速(部分场景可修复渲染异常):
java -Dsun.java2d.d3d=true SwingLang
内容的提问来源于stack exchange,提问作者Арсений Коротков
相关产品推荐
相关产品推荐

