質問
SWTには、さまざまなオペレーティングシステムで機能する固定幅フォントを簡単に取得する方法がありますか?
たとえば。これはLinuxでは動作しますが、Windowsでは動作しません:
Font mono = new Font(parent.getDisplay(), "Mono", 10, SWT.NONE);
またはヌルになるまでさまざまなフォント(Consolas、Terminal、Monaco、Mono)をロードしようとするメソッドが必要ですか?または、起動時にプロパティファイルで指定することもできます。
ディスプレイからシステムフォントを取得しようとしましたが、モノスペースではありませんでした。
解決
フォント設定ファイル 国際化サポート関連APIのJDKドキュメント内、論理フォントの概念は、デフォルトのフォント設定ファイルで物理フォントにマッピングされる特定のプラットフォームに依存しないフォントを定義するために使用されます。
Javaプラットフォームは、すべての実装がサポートする必要がある5つの論理フォント名を定義します:Serif、SansSerif、Monospaced、Dialog、およびDialogInput。これらの論理フォント名は、実装依存の方法で物理フォントにマップされます。
だからあなたの場合、私はしようとする
Font mono = new Font(parent.getDisplay()、" Monospaced&quot ;, 10、SWT.NONE);
コードが実行されている現在のプラットフォームの物理的な等幅フォントへのハンドルを取得します。
編集:SWTは論理フォントについて何も知らないようです(バグ48055 で詳しく説明されています)。このバグレポートでは、物理的なフォントの名前をAWTフォントから取得できるハック的な回避策が提案されました...
他のヒント
日食は明らかにテキストフィールド、コンソールなどで使用するために等幅フォントにアクセスする必要があることに気づくまで、私はしばらくこれに頭をぶつけました。少し掘り返しました:
Font terminalFont = JFaceResources.getFont(JFaceResources.TEXT_FONT);
あなたが興味を持っているのがモノスペースフォントを手に入れているだけなら、どちらが機能します。
編集:または@ctronのコメントに基づいて:
Font font = JFaceResources.getTextFont();
編集:警告(@Liiのコメントに基づく):これにより、構成済みのテキストフォントが取得されます。これはユーザーが上書きでき、固定幅フォントではない場合があります。ただし、たとえばエディターやコンソールで使用されるフォントと一致します。これはおそらくおそらく欲しいものです。
私の知る限り、AWT APIは基礎となるフォント情報を公開しません。あなたがそれに到達することができれば、私はそれが実装依存であることを期待するでしょう。確かに、いくつかのJRE libディレクトリのフォントマッピングファイルを比較すると、一貫した方法で定義されていないことがわかります。
独自のフォントを読み込むこともできますが、プラットフォームに必要なものが付属していることを知っていれば、それは少し無駄に思えます。
これは、JREフォントをロードするハックです。
private static Font loadMonospacedFont(Display display) {
String jreHome = System.getProperty("java.home");
File file = new File(jreHome, "/lib/fonts/LucidaTypewriterRegular.ttf");
if (!file.exists()) {
throw new IllegalStateException(file.toString());
}
if (!display.loadFont(file.toString())) {
throw new IllegalStateException(file.toString());
}
final Font font = new Font(display, "Lucida Sans Typewriter", 10,
SWT.NORMAL);
display.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
font.dispose();
}
});
return font;
}
IBM / Win32 / JRE1.4、Sun / Win32 / JRE1.6、Sun / Linux / JRE1.6で動作しますが、非常に脆弱なアプローチです。 I18Nのニーズによっては、問題も発生する可能性があります(チェックしていません)。
別のハックは、プラットフォームで利用可能なフォントをテストすることです:
public class Monotest {
private static boolean isMonospace(GC gc) {
final String wide = "wgh8";
final String narrow = "1l;.";
assert wide.length() == narrow.length();
return gc.textExtent(wide).x == gc.textExtent(narrow).x;
}
private static void testFont(Display display, Font font) {
Image image = new Image(display, 100, 100);
try {
GC gc = new GC(image);
try {
gc.setFont(font);
System.out.println(isMonospace(gc) + "\t"
+ font.getFontData()[0].getName());
} finally {
gc.dispose();
}
} finally {
image.dispose();
}
}
private static void walkFonts(Display display) {
final boolean scalable = true;
for (FontData fontData : display.getFontList(null, scalable)) {
Font font = new Font(display, fontData);
try {
testFont(display, font);
} finally {
font.dispose();
}
}
}
public static void main(String[] args) {
Display display = new Display();
try {
walkFonts(display);
} finally {
display.dispose();
}
}
}
これは、ロケールの問題にさらされる可能性があるため、おそらく良い方法ではありません。それに、最初に出会う等幅フォントがいくつかの曲がりくねったアイコンセットでないかどうかはわかりません。
最善のアプローチは、フォント/ロケールマッピングホワイトリストに基づいて最善の推測を行い、ユーザーが FontDialog 。
同じ問題を抱えている人は、任意のフォントttfファイルをダウンロードし、リソースフォルダー(私の場合は/font/**.ttf)に入れて、このメソッドを応用。仕事は100%です。
public Font loadDigitalFont(int policeSize) {
URL fontFile = YouClassName.class
.getResource("/fonts/DS-DIGI.TTF");
boolean isLoaded = Display.getCurrent().loadFont(fontFile.getPath());
if (isLoaded) {
FontData[] fd = Display.getCurrent().getFontList(null, true);
FontData fontdata = null;
for (int i = 0; i < fd.length; i++) {
if (fd[i].getName().equals("DS-Digital")) {
fontdata = fd[i];
break;
}}
if (fontdata != null) {
fontdata.setHeight(policeSize);
fontdata.setStyle(SWT.BOLD);return new Font(getDisplay(), fontdata));}
}return null; }
モノスペースフォントだけが必要な場合は、「クーリエ」を使用します。 =&gt; 新しいフォント(display、&quot; Courier&quot;、10、SWT.NORMAL)