SWT-OS agnostic façon d'obtenir une police monospacée

y a-t-il un moyen en SWT pour obtenir une police mono-placée simplement, qui fonctionne à travers différents systèmes d'exploitation?

Par exemple. cela fonctionne sous Linux, mais pas sous Windows:


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

ou dois-je avoir une méthode qui essaie de charger des polices variables (consoles, Terminal, Monaco, Mono) jusqu'à ce qu'on ne soit pas null? Alternativement je pourrais le spécifier dans un fichier de propriétés au démarrage.

j'ai essayé d'obtenir la police du système à partir de L'affichage, mais ce n'était pas monospacé.

27
demandé sur JeeBee 2008-10-21 15:50:49

5 réponses

selon la section sur Fichiers De Configuration De La Police dans la documentation JDK de Soutien À L'Internationalisation - APIs liés, le concept de Logique De Police s est utilisé pour définir certaines polices indépendantes de la plate-forme qui sont mises en correspondance avec des polices physiques dans les fichiers de configuration de polices par défaut:

La plate-forme Java définit cinq noms de police logiques que chaque implémentation doit prendre en charge: Serif, SansSerif, Monospaced, Dialog, et DialogInput. Ces noms de police logiques sont mis en correspondance avec les polices physiques de manière dépendante de l'implémentation.

alors dans votre cas, j'essaierais

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

pour obtenir un handle vers la physique police à chasse fixe de la plate-forme actuelle de votre code est en cours d'exécution sur.

Modifier: il semble que SWT ne sache rien des polices logiques ( bogue 48055 sur eclipse.org décrit en détail). Dans ce rapport de bug un hackish une solution de contournement a été suggérée, où le nom de la police physique peut être récupéré à partir d'une police AWT...

15
répondu fhe 2008-10-21 19:06:15

j'ai passé un moment à me cogner la tête contre celle-ci jusqu'à ce que je réalise qu'évidemment eclipse doit avoir accès à une police monospace pour l'utiliser dans ses champs de texte, console, etc. Creuser un peu tourné vers le haut:

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

Qui fonctionne si vous êtes intéressés à obtenir de police à espacement fixe.

Edit: ou basé sur le commentaire de @ctron:

Font font = JFaceResources.getTextFont();

Edit: mise en garde (basée sur le commentaire de @Lii): cela vous donnera la configuration Police texte, qui peut être remplacée par l'utilisateur et ne peut pas être une police monospace. Toutefois, il sera compatible avec, par exemple, la police utilisée dans l'éditeur et de la console qui est probablement ce que vous voulez.

35
répondu Bartleby 2018-07-28 10:05:36

à ma connaissance, L'API AWT n'expose pas les informations de police sous-jacentes. Si vous pouvez l'obtenir, je m'attends à ce qu'il soit dépendant de l'implémentation. Certainement, en comparant les fichiers de mappage des polices dans quelques répertoires JRE lib, je peux voir qu'ils ne sont pas définis de manière cohérente.

vous pouvez charger vos propres polices, mais cela semble un peu inutile étant donné que vous savez que la plate-forme vient avec ce dont vous avez besoin.

C'est un hack qui charge un JRE police de caractères:

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

Il fonctionne sur IBM/Win32/JRE1.4, Soleil/Win32/JRE1.6, Soleil/Linux/JRE1.6, mais est assez fragile approche. Selon vos besoins pour I18N, il pourrait y avoir des problèmes là aussi (je n'ai pas vérifié).

un autre hack serait de tester les polices disponibles sur la plateforme:

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

}

ce n'est probablement pas une bonne approche car cela peut vous exposer à des problèmes locaux. De plus, vous ne savez pas si la première police monospacée que vous rencontrez n'est pas les enroulements du jeu d'icônes.

la meilleure approche est peut-être de prendre votre meilleure estimation basée sur une liste blanche de cartographie police/locale et de s'assurer que les utilisateurs peuvent facilement reconfigurer L'interface utilisateur pour s'adapter via FontDialog.

4
répondu McDowell 2008-10-22 15:50:58

pour les personnes qui ont le même problème, vous pouvez télécharger n'importe quel fichier TTF, le mettre dans le dossier ressource (dans mon cas /font/**.ttf) et ajoutez cette méthode à votre application. C'est un travail de 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;   }
3
répondu freesniper 2013-03-07 11:23:05

Si vous voulez juste une police à chasse fixe l'utilisation de "Messager" => new Font(display, "Courier", 10, SWT.NORMAL)

1
répondu Sumit Singh 2013-08-23 10:16:30