Font
オブジェクトからネイティブフォント名を取得する方法はJavaにありますか?
このコード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;
}