Java中有没有办法从Font
对象中获取本机字体名称?
我使用此代码获取我的字体Font.decode("Serif")
,出于调试目的,我想知道使用的本机字体。
可能没那么简单。有些字体是由很多物理字体组成的,不同的字形使用不同的物理字体。
例如,在我的 Windows 系统上,Serif 字体使用 12 种物理字体:
以下代码可以将字体分解为其物理组件。它使用反射黑客来访问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);
}
}
prunge的答案几乎是完美的,只是它实际上并没有公开原生(物理)字体的名称。对 describeFont2D 方法的以下微小更改通过再次利用 Java 反射来解决问题:
不要忘记导入 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 );
}
如果系统字体可用,此代码将获取系统字体,如果由于某种原因它们不可用,则将获取默认系列:
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;
}