Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中检索本机字体名称?_Java_Fonts - Fatal编程技术网

如何在Java中检索本机字体名称?

如何在Java中检索本机字体名称?,java,fonts,Java,Fonts,Java中有没有一种方法可以从font对象中获取本机字体名称 我使用此代码Font.decode(“Serif”)获取字体,出于调试目的,我想知道使用的本机字体 如果系统字体可用,此代码将获取系统字体;如果由于某些原因,系统字体不可用,此代码将获取默认系列: static String[] AS_System_Fonts = null; public static String[] getFontFamilies(){ if( AS_System_Fonts != null ) retu

Java中有没有一种方法可以从
font
对象中获取本机字体名称


我使用此代码
Font.decode(“Serif”)
获取字体,出于调试目的,我想知道使用的本机字体

如果系统字体可用,此代码将获取系统字体;如果由于某些原因,系统字体不可用,此代码将获取默认系列:

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;
}

可能没那么简单。有些字体由许多物理字体组成,对不同的字形使用不同的物理字体

例如,在我的Windows系统上,衬线字体使用12种物理字体:

  • **TrueType字体:Family=泰晤士报新罗马名称=泰晤士报新罗马风格=0文件名=C:\Windows\Fonts\Times.TTF
  • **TrueType字体:Family=Wingdings Name=Wingdings style=0 fileName=C:\Windows\Fonts\WINGDING.TTF
  • **TrueType字体:Family=Symbol Name=Symbol style=0文件名=C:\Windows\Fonts\Symbol.TTF
  • **TrueType字体:Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0\u 37\jre\lib\Font\LucidaSansRegular.ttf
  • **TrueType字体:Family=MingLiU Name=MingLiU style=0 fileName=C:\Windows\Fonts\MingLiU.TTC
  • **TrueType字体:Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0\u 37\jre\lib\Font\LucidaSansRegular.ttf
  • **TrueType字体:Family=SimSun Name=SimSun style=0文件名=C:\Windows\Fonts\SimSun.TTC
  • **TrueType字体:Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0\u 37\jre\lib\Font\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配合使用):

导入java.awt.Font;
导入java.lang.reflect.Method;
导入java.util.Locale;
导入sun.font.CompositeFont;
导入sun.font.Font2D;
导入sun.font.PhysicalFont;
公共类测试仪
{
公共静态void main(字符串…参数)
抛出异常
{
Font Font=新字体(“衬线”,Font.PLAIN,12);
描述字体(字体);
}
专用静态无效描述字体(字体)
抛出异常
{
方法Method=font.getClass().getDeclaredMethod(“getFont2D”);
方法setAccessible(true);
Font2D f=(Font2D)方法。调用(font);
描述2d(f);
}
私有静态无效描述符Font2D(Font2D字体)
{
如果(复合字体的字体实例)
{
System.out.println(“Font'”+Font.getFontName(Locale.getDefault())+“”由以下部分组成:”;
CompositeFont cf=(CompositeFont)字体;
对于(int i=0;i”+字体);
}
}
的答案近乎完美,只是它实际上没有公开本机(物理)字体的名称。对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 );
}
private static void descripeFont2D(Font2D字体)引发异常{
如果(复合字体的字体实例){
System.out.println(“Font'”+Font.getFontName(Locale.getDefault())+“”由以下部分组成:”;
CompositeFont cf=(CompositeFont)字体;

对于(int i=0;i你说的“本机字体”是什么意思?有一种方法,因为有Java应用程序显示系统上安装的本机字体(例如,IntelliJ IDEA在我的Linux机器上显示了像
DejaVu Sans Mono
这样的字体列表)。只是我不知道实现这一点的确切步骤:)你尝试过font.getFontName()吗?@TylerDurden By native font我指的是物理字体,如“Times New Roman”,“Arial”…Serif是Java中定义的逻辑字体之一的名称,Java将这些逻辑字体映射到物理字体。顺便说一句,getFontName为逻辑字体Serif提供了“Serif”,但为我提供了“Times Roman”对于逻辑字体时代。我没有进一步研究,但我猜测这些是“本机”字体名称(我在OS X上)。除了非标准变量命名(AS_System_Fonts将更好地命名为systemFonts),回答得好!关于变量名,很抱歉,这是一个具有专门命名约定的实用工具套件的产物,请随意重命名,我们还需要导入
sun.font.CFont
。也就是说,
sun.font.CFont
仅适用于Mac OS X,这将此修改方法的使用限制在该平台上。
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 );
}