首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JBuilder 中文光標錯位終極解決方案:修復 Sun JDK font.properties.zh 缺陷

     編輯:Java 相關知識

JBuilder 在中文系統下的光標錯位問題困擾開發者多年,常被誤認為是 Borland 的 Bug。實際根因在於 Sun JDK 的 `font.properties.zh` 缺失英文字體的 Bold/Italic 映射,導致 AWT 字體測量錯誤。本文提供徹底修復方案:直接修正 JDK 配置文件,一次修復惠及所有基於 AWT/Swing 的 Java 應用,無需犧牲代碼可讀性(保持 Courier New 等優秀編程字體)。

問題根因分析

JDK 通過 `font.properties.{locale}` 定義邏輯字體到物理字體的映射。Sun 提供的中文版配置存在關鍵缺陷:

  • 缺失 Bold/Italic 映射:`dialog.bold.0`、`sansserif.italic.0` 等條目指向不存在的字體或空值
  • 字體度量錯誤:AWT 根據字體度量計算光標位置,映射錯誤導致度量與實際渲染不符
  • 影響範圍:所有使用邏輯字體的 AWT/Swing 組件,包括 JBuilder 編輯器、Eclipse SWT(AWT 模式)、NetBeans 早期版本

修復前配置缺陷示例


# 原配置缺陷片段
dialog.plain.0=Dialog,DEFAULT_CHARSET
dialog.bold.0=Dialog Bold,DEFAULT_CHARSET      # ❌ 系統無 "Dialog Bold" 字體
dialog.italic.0=Dialog Italic,DEFAULT_CHARSET  # ❌ 系統無 "Dialog Italic" 字體
sansserif.plain.0=MS Sans Serif,DEFAULT_CHARSET
sansserif.bold.0=MS Sans Serif Bold,DEFAULT_CHARSET  # ❌ 字體名錯誤
monospaced.plain.0=Monospaced,DEFAULT_CHARSET
# 缺失 monospaced.bold/italic 等關鍵映射

完整修正配置:font.properties.zh

路徑:`$JAVA_HOME/jre/lib/font.properties.zh`(備份原文件後替換)


# @(#)font.properties.zh 1.16 00/10/06 修正版
# AWT Font default Properties for Chinese Windows - 完整 Bold/Italic 映射

# Dialog 字體族
dialog.plain.0=Arial,ANSI_CHARSET
dialog.plain.1=\u5b8b\u4f53,GB2312_CHARSET
dialog.plain.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialog.plain.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialog.bold.0=Arial Bold,ANSI_CHARSET
dialog.bold.1=\u5b8b\u4f53,GB2312_CHARSET
dialog.bold.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialog.bold.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialog.italic.0=Arial Italic,ANSI_CHARSET
dialog.italic.1=\u5b8b\u4f53,GB2312_CHARSET
dialog.italic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialog.italic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialog.bolditalic.0=Arial Bold Italic,ANSI_CHARSET
dialog.bolditalic.1=\u5b8b\u4f53,GB2312_CHARSET
dialog.bolditalic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialog.bolditalic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED

# DialogInput 字體族 (編輯器常用)
dialoginput.plain.0=Courier New,ANSI_CHARSET
dialoginput.plain.1=\u5b8b\u4f53,GB2312_CHARSET
dialoginput.plain.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.plain.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.bold.0=Courier New Bold,ANSI_CHARSET
dialoginput.bold.1=\u5b8b\u4f53,GB2312_CHARSET
dialoginput.bold.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.bold.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.italic.0=Courier New Italic,ANSI_CHARSET
dialoginput.italic.1=\u5b8b\u4f53,GB2312_CHARSET
dialoginput.italic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.italic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.bolditalic.0=Courier New Bold Italic,ANSI_CHARSET
dialoginput.bolditalic.1=\u5b8b\u4f53,GB2312_CHARSET
dialoginput.bolditalic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
dialoginput.bolditalic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED

# Serif 字體族
serif.plain.0=Times New Roman,ANSI_CHARSET
serif.plain.1=\u5b8b\u4f53,GB2312_CHARSET
serif.plain.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.plain.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
serif.bold.0=Times New Roman Bold,ANSI_CHARSET
serif.bold.1=\u5b8b\u4f53,GB2312_CHARSET
serif.bold.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.bold.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
serif.italic.0=Times New Roman Italic,ANSI_CHARSET
serif.italic.1=\u5b8b\u4f53,GB2312_CHARSET
serif.italic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.italic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
serif.bolditalic.0=Times New Roman Bold Italic,ANSI_CHARSET
serif.bolditalic.1=\u5b8b\u4f53,GB2312_CHARSET
serif.bolditalic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.bolditalic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED

# SansSerif 字體族
sansserif.plain.0=Arial,ANSI_CHARSET
sansserif.plain.1=\u5b8b\u4f53,GB2312_CHARSET
sansserif.plain.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.plain.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.bold.0=Arial Bold,ANSI_CHARSET
sansserif.bold.1=\u5b8b\u4f53,GB2312_CHARSET
sansserif.bold.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.bold.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.italic.0=Arial Italic,ANSI_CHARSET
sansserif.italic.1=\u5b8b\u4f53,GB2312_CHARSET
sansserif.italic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.italic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.bolditalic.0=Arial Bold Italic,ANSI_CHARSET
sansserif.bolditalic.1=\u5b8b\u4f53,GB2312_CHARSET
sansserif.bolditalic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
sansserif.bolditalic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED

# Monospaced 字體族 (代碼編輯器核心)
monospaced.plain.0=Courier New,GB2312_CHARSET
monospaced.plain.1=\u5b8b\u4f53,GB2312_CHARSET
monospaced.plain.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.plain.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.bold.0=Courier New Bold,GB2312_CHARSET
monospaced.bold.1=\u5b8b\u4f53,GB2312_CHARSET
monospaced.bold.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.bold.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.italic.0=Courier New Italic,GB2312_CHARSET
monospaced.italic.1=\u5b8b\u4f53,GB2312_CHARSET
monospaced.italic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.italic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.bolditalic.0=Courier New Bold Italic,GB2312_CHARSET
monospaced.bolditalic.1=\u5b8b\u4f53,GB2312_CHARSET
monospaced.bolditalic.2=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
monospaced.bolditalic.3=Symbol,SYMBOL_CHARSET,NEED_CONVERTED

# 字體文件映射 (加速啟動)
filename.\u5b8b\u4f53=SIMSUN.TTF
filename.Arial=ARIAL.TTF
filename.Arial_Bold=ARIALBD.TTF
filename.Arial_Italic=ARIALI.TTF
filename.Arial_Bold_Italic=ARIALBI.TTF
filename.Courier_New=COUR.TTF
filename.Courier_New_Bold=COURBD.TTF
filename.Courier_New_Italic=COURI.TTF
filename.Courier_New_Bold_Italic=COURBI.TTF
filename.Times_New_Roman=TIMES.TTF
filename.Times_New_Roman_Bold=TIMESBD.TTF
filename.Times_New_Roman_Italic=TIMESI.TTF
filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF
filename.WingDings=WINGDING.TTF
filename.Symbol=SYMBOL.TTF

# 字符集轉換器
fontcharset.dialog.1=sun.io.CharToByteGBK
fontcharset.dialog.2=sun.awt.windows.CharToByteWingDings
fontcharset.dialog.3=sun.awt.CharToByteSymbol
fontcharset.dialoginput.1=sun.io.CharToByteGBK
fontcharset.dialoginput.2=sun.awt.windows.CharToByteWingDings
fontcharset.dialoginput.3=sun.awt.CharToByteSymbol
fontcharset.serif.1=sun.io.CharToByteGBK
fontcharset.serif.2=sun.awt.windows.CharToByteWingDings
fontcharset.serif.3=sun.awt.CharToByteSymbol
fontcharset.sansserif.1=sun.io.CharToByteGBK
fontcharset.sansserif.2=sun.awt.windows.CharToByteWingDings
fontcharset.sansserif.3=sun.awt.CharToByteSymbol
fontcharset.monospaced.1=sun.io.CharToByteGBK
fontcharset.monospaced.2=sun.awt.windows.CharToByteWingDings
fontcharset.monospaced.3=sun.awt.CharToByteSymbol

# 排除範圍 (避免中文字符被誤判為符號字體)
exclusion.dialog.plain.0=00a0-f8ff
exclusion.dialog.italic.0=00a0-f8ff
exclusion.dialog.bold.0=00a0-f8ff
exclusion.dialog.bolditalic.0=00a0-f8ff
exclusion.dialoginput.plain.0=00a0-f8ff
exclusion.dialoginput.italic.0=00a0-f8ff
exclusion.dialoginput.bold.0=00a0-f8ff
exclusion.dialoginput.bolditalic.0=00a0-f8ff
exclusion.serif.plain.0=00a0-f8ff
exclusion.serif.italic.0=00a0-f8ff
exclusion.serif.bold.0=00a0-f8ff
exclusion.serif.bolditalic.0=00a0-f8ff
exclusion.sansserif.plain.0=00a0-f8ff
exclusion.sansserif.italic.0=00a0-f8ff
exclusion.sansserif.bold.0=00a0-f8ff
exclusion.sansserif.bolditalic.0=00a0-f8ff
exclusion.monospaced.italic.0=00a0-f8ff
exclusion.monospaced.bold.0=00a0-f8ff
exclusion.monospaced.bolditalic.0=00a0-f8ff

# 默認字符
default.char=2751

修復效果驗證

場景修復前修復後
JBuilder 編輯器光標中英文混排時光標偏移 2-4 像素光標精確對齊字符邊界
代碼高亮 Bold/Italic關鍵字加粗導致後續字符位移語法高亮不影響佈局
Courier New 等寬字體Bold 版本顯示為宋體或亂碼完美顯示 Courier New Bold/Italic
其他 Java 應用同樣存在光標/佈局問題一體修復,全局生效

適用範圍與注意事項

  • 適用 JDK 版本:JDK 1.3/1.4/1.5/1.6 早期版本(JDK 1.6u10+ 已內建修復)
  • 適用 IDE:JBuilder 所有版本、Eclipse (AWT/SWT 混合模式)、NetBeans 6.x 之前版本
  • 操作步驟:
    1. 定位 `$JAVA_HOME/jre/lib/font.properties.zh`
    2. 備份原文件:`cp font.properties.zh font.properties.zh.bak`
    3. 替換為上述修正內容
    4. 重啟 IDE 驗證
  • Linux/macOS:對應修改 `font.properties.zh_CN` 或 `font.properties.zh_TW`

避坑指南:兩種常見錯誤方案

❌ 方案一:強制編輯器字體改為宋體

副作用:英文字符顯示為宋體等寬字形,字符寬度不一,代碼對齊極難,閱讀體驗極差

❌ 方案二:取消編輯器字體 Bold 屬性

副作用:關鍵字、類名、字符串失去語法高亮區分度,代碼可讀性大幅下降

根因歸責

這是 Sun Microsystems 在 JDK 國際化(i18n)實現上的明確缺陷:未為中文 Locale 提供完整的邏輯字體 Bold/Italic/BoldItalic 映射。Oracle 接管後在 JDK 6u10 (2008) 修復此問題。對於維護舊版本 JDK 的企業環境,本配置修正是零成本、零風險的最優解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved