2012-10-25 60 views
1

在Java中有從Font對象獲取本機字體名稱的方法嗎?如何檢索Java中的本機字體名稱?

我得到我的字體使用此代碼Font.decode("Serif")和調試目的我想知道使用的本機字體。

+1

你是什麼意思的「本地字體」? –

+0

因爲有Java應用程序可以顯示系統上安裝的本機字體(例如,IntelliJ IDEA顯示我的Linux機器上的'DejaVu Sans Mono'等字體列表),所以這裏已經有了。這只是我沒有確切的步驟來實現這個:) –

+0

你試過font.getFontName()嗎? – GreyBeardedGeek

回答

5

它可能不是那麼簡單。某些字體由許多物理字體組成,對不同的字形使用不同的物理字體。

例如,我的Windows系統上的Serif字體使用12種物理字體:

  • **的TrueType字體:家庭= Times New Roman字體名稱=宋體風格= 0文件名= C:\ WINDOWS \字體\ TIMES.TTF
  • **的TrueType字體:家庭=宋體名稱=宋體風格= 0文件名= C:\ WINDOWS \ Fonts \中WINGDING.TTF
  • **的TrueType字體:家庭=符號名稱=符號樣式= 0 fileName = C:\ Windows \ Fonts \ SYMBOL.TTF
  • ** TrueType字體:Family = Lucida Sans Name = Lucida Sans Regular style = 0 file Name = C:\ Java \ jdk \ jdk1.6.0_37 \ jre \ lib \ fonts \ LucidaSansRegular.ttf
  • ** TrueType字體:Family = MingLiU Name = MingLiU style = 0 fileName = C:\ Windows \ Fonts \ MINGLIU .TTC
  • **的TrueType字體:家庭=龍力三世名稱=龍力三世經常風格= 0文件名= C:\的Java \ jdk的\ jdk1.6.0_37 \ JRE \ lib文件\ Fonts \中LucidaSansRegular.ttf
  • ** TrueType字體:Family = SimSun Name = SimSun style = 0 fileName = C:\ Windows \ Fonts \ SIMSUN.TTC
  • ** TrueType字體:Family = Lucida Sans Name = Lucida Sans Regular style = 0 fileName = C:\ Java \ jdk \ jdk1.6.0_37 \ jre \ lib \ fonts \ LucidaSansRegular.ttf
  • ** TrueType字體:Family = MS Mincho Name = MS Mincho style = 0 fileName = C:\ Windows \ Fonts \ MSMINCHO.TTC
  • ** TrueType字體:Family = Batang Name = Batang style = 0 fileName = C:\ Windows \ Fonts \ batang.TTC
  • ** TrueType字體: Family = MingLiU-ExtB Name = MingLiU-ExtB style = 0 fileName = C:\ Windows \ Fonts \ MINGLIUB.TTC
  • ** TrueType字體:Family = SimSun-ExtB Name = SimSun-ExtB style = 0 fileName = C: \ Windows \ Fonts \ SIMSUNB.TTF

以下代碼可以將字體分解爲其物理組件。它採用了反射黑客訪問sun.awt.Font2D對象,所以需要您自擔風險使用(與Oracle的Java 6u37工作):

import java.awt.Font; 
import java.lang.reflect.Method; 
import java.util.Locale; 

import sun.font.CompositeFont; 
import sun.font.Font2D; 
import sun.font.PhysicalFont; 

public class FontTester 
{ 
    public static void main(String... args) 
    throws Exception 
    { 
     Font font = new Font("Serif", Font.PLAIN, 12); 
     describeFont(font); 
    } 

    private static void describeFont(Font font) 
    throws Exception 
    { 
     Method method = font.getClass().getDeclaredMethod("getFont2D"); 
     method.setAccessible(true); 
     Font2D f = (Font2D)method.invoke(font); 

     describeFont2D(f); 
    } 

    private static void describeFont2D(Font2D font) 
    { 
     if (font instanceof CompositeFont) 
     { 
      System.out.println("Font '" + font.getFontName(Locale.getDefault()) + "' is composed of:"); 

      CompositeFont cf = (CompositeFont)font; 
      for (int i = 0; i < cf.getNumSlots(); i++) 
      { 
       PhysicalFont pf = cf.getSlotFont(i); 
       describeFont2D(pf); 
      } 
     } 
     else 
      System.out.println("-> " + font); 
    } 
} 
1

此代碼將得到系統的字體,如果他們是可用的,並且會得到默認的家庭,如果由於某種原因,他們無法使用:

static String[] AS_System_Fonts = null; 
public static String[] getFontFamilies(){ 
    if(AS_System_Fonts != null) return AS_System_Fonts; 
    java.awt.GraphicsEnvironment gEnv = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    AS_System_Fonts = gEnv.getAvailableFontFamilyNames(); 
    if(AS_System_Fonts == null){ // should not happen 
     AS_System_Fonts = new String[8]; 
     AS_System_Fonts[0] = "Serif"; 
     AS_System_Fonts[1] = "Sans-Serif"; 
     AS_System_Fonts[2] = "Monospaced"; 
     AS_System_Fonts[3] = "Dialog"; 
     AS_System_Fonts[4] = "Dialog Input"; 
     AS_System_Fonts[5] = "Lucida Bright"; 
     AS_System_Fonts[6] = "Lucida Sans"; 
     AS_System_Fonts[7] = "Lucida Sans Typewriter"; 
    } 
    return AS_System_Fonts; 
} 
+0

以外的非標準變量命名(AS_System_Fonts會好得多,命名爲systemFonts),很好的答案! – GreyBeardedGeek

+0

對於變量名稱感到遺憾,它是具有專門命名約定的實用工具包中出現的工件,請隨時重命名爲 –

0

prunge的回答是近乎完美的,但它實際上並沒有露出天然(物理)字體的名稱。通過再次利用Java反射,describeFont2D方法發生如下細微變化:

不要忘記導入java.lang.reflect.Field;

private static void describeFont2D(Font2D font) throws Exception{ 
    if(font instanceof CompositeFont){ 
     System.out.println("Font '"+font.getFontName(Locale.getDefault())+"' is composed of:"); 
     CompositeFont cf = (CompositeFont)font; 
     for(int i = 0; i<cf.getNumSlots(); i++){ 
      PhysicalFont pf = cf.getSlotFont(i); 
      describeFont2D(pf); 
     } 
    }else if(font instanceof CFont){ 
     Field field = CFont.class.getDeclaredField("nativeFontName"); 
     field.setAccessible(true); 
     String nativeFontName = (String)field.get(font);     
     System.out.println("-> "+nativeFontName); 
    }else 
     System.out.println("-> "+font); 
} 
+0

[@ dan-borque](https://stackoverflow.com/users/77479/dan-bourque ),我們還需要導入'sun.font.CFont'。也就是說,'sun.font.CFont'僅適用於Mac OS X,這限制了此修改方法在該平臺上的使用。 –