28

SWT で、さまざまなオペレーティング システムで動作する等幅フォントを簡単に取得する方法はありますか?

例えば。これは Linux では機能しますが、Windows では機能しません。


Font mono = new Font(parent.getDisplay(), "Mono", 10, SWT.NONE);

または、null になるまでさまざまなフォント (Consolas、Terminal、Monaco、Mono) を読み込もうとするメソッドが必要ですか? または、起動時にプロパティ ファイルで指定することもできます。

Display からシステム フォントを取得しようとしましたが、等幅ではありませんでした。

4

5 に答える 5

39

テキストフィールドやコンソールなどで使用するために、明らかにEclipseがモノスペースフォントにアクセスできる必要があることに気付くまで、私はこれに対して頭をぶつけました。

Font terminalFont = JFaceResources.getFont(JFaceResources.TEXT_FONT);

あなたが興味を持っているのが等幅フォントを手に入れることだけなら、これはうまくいきます。

編集:または@ctronのコメントに基づく:

Font font = JFaceResources.getTextFont();

編集:警告 (@Lii のコメントに基づく): これにより、構成されたテキスト フォントが取得されます。これは、ユーザーがオーバーライドでき、モノスペース フォントではない可能性があります。ただし、たとえば、エディターやコンソールで使用されるフォントとは一致しますが、これはおそらくあなたが望むものです。

于 2012-02-27T14:57:54.897 に答える
16

Internationalization Support関連 APIの JDK ドキュメントのFont Configuration Filesに関するセクションによると、Logical Fontの概念は、デフォルトのフォント構成ファイルで物理フォントにマップされる特定のプラットフォームに依存しないフォントを定義するために使用されます。

Java プラットフォームでは、すべての実装でサポートする必要がある 5 つの論理フォント名 (Serif、SansSerif、Monospaced、Dialog、および DialogInput) が定義されています。これらの論理フォント名は、実装に依存する方法で物理フォントにマップされます。

だからあなたの場合、私は試してみます

Font mono = new Font(parent.getDisplay(), "Monospaced", 10, SWT.NONE);

コードが実行されている現在のプラットフォームの物理等幅フォントへのハンドルを取得します。

編集: SWT は論理フォントについて何も知らないようです ( eclipse.org のBug 48055で詳しく説明されています)。このバグレポートでは、物理フォントの名前を AWT フォントから取得できるハック的な回避策が提案されています...

于 2008-10-21T18:14:42.463 に答える
4

私の知る限り、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を介して自分に合うように UI を簡単に再構成できることを確認することです。

于 2008-10-22T15:50:58.713 に答える
3

同じ問題を抱えている人は、任意のフォント 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;   }
于 2013-03-07T11:23:05.853 に答える
1

等幅フォントだけが必要な場合は、「Courier」を使用 =>new Font(display, "Courier", 10, SWT.NORMAL)

于 2008-12-11T11:38:28.327 に答える