Question

Existe-t-il un moyen dans SWT d’obtenir une police monospace qui fonctionne avec 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 ai-je besoin d'une méthode qui tente de charger différentes polices (Consolas, Terminal, Monaco, Mono) jusqu'à ce que l'une d'elles ne soit plus nulle? Sinon, je pourrais le spécifier dans un fichier de propriétés au démarrage.

J'ai essayé d'obtenir la police système de Display, mais ce n'était pas monospace.

Était-ce utile?

La solution

Conformément à la section Fichiers de configuration de police dans la documentation JDK des API de prise en charge de l'internationalisation , le concept de police logique est utilisé pour définir certaines polices indépendantes de la plate-forme qui sont mappées sur des polices physiques dans les fichiers de configuration de police par défaut:

  

La plate-forme Java définit cinq noms de polices logiques que chaque implémentation doit prendre en charge: Serif, SansSerif, Monospaced, Dialog et DialogInput. Ces noms de polices logiques sont mappés sur les polices physiques de manière dépendante de la mise en œuvre.

Donc dans votre cas, j'essaierais

Police mono = nouvelle police (parent.getDisplay (), "Monospaced", 10, SWT.NONE);

pour obtenir un descripteur de la police physique monospaced de la plate-forme actuelle sur laquelle votre code est exécuté.

Modifier : il semble que SWT ne connaisse rien des polices logiques ( Le bogue 48055 sur eclipse.org décrit cela en détail). Dans ce rapport de bogue, une solution de contournement a été suggérée, dans laquelle le nom de la police physique peut être extrait d'une police AWT ...

Autres conseils

J'ai passé un certain temps à me cogner la tête jusqu'à ce que je réalise qu'éclipse doit évidemment avoir accès à une police monospace pour pouvoir être utilisée dans ses champs de texte, sa console, etc.

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

Ce qui fonctionne si tout ce qui vous intéresse est de mettre la main sur une police monospace.

Modifier: Ou d'après le commentaire de @ ctron:

Font font = JFaceResources.getTextFont();

Modifier: Avertissement (basé sur le commentaire de @ Lii): vous obtiendrez la police de texte configurée, qui peut être remplacée par l'utilisateur et peut ne pas être une police monospace. Cependant, elle sera compatible avec, par exemple, la police utilisée dans l'éditeur et la console, qui est probablement ce que vous voulez.

À ma connaissance, l'API AWT n'expose pas les informations de police sous-jacentes. Si vous pouvez y arriver, je suppose que cela dépend de la mise en œuvre. Certes, en comparant les fichiers de mappage de polices dans quelques répertoires JRE lib, je constate qu’ils ne sont pas définis de manière cohérente.

Vous pouvez charger vos propres polices, mais cela semble un peu inutile, sachant que la plate-forme est fournie avec ce dont vous avez besoin.

Ceci est un hack qui charge une police 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;
}

Cela fonctionne sous IBM / Win32 / JRE1.4, Sun / Win32 / JRE1.6, Sun / Linux / JRE1.6, mais c’est une approche assez fragile. En fonction de vos besoins pour I18N, cela pourrait également poser problème (je n’ai pas vérifié).

Un autre hack serait de tester les polices disponibles sur la plate-forme:

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 de localisation. En outre, vous ne savez pas si la première police à espacement fixe que vous rencontrerez ne fait pas partie d’un ensemble d’icônes d’enroulement.

La meilleure approche consiste peut-être simplement à prendre votre meilleure hypothèse en vous basant sur une liste blanche de mappage polices / paramètres régionaux et à vous assurer que les utilisateurs peuvent facilement reconfigurer l'interface utilisateur à leur guise via FontDialog .

Pour les personnes qui ont le même problème, vous pouvez télécharger n’importe quel fichier ttf de police, le placer dans le dossier de ressources (dans mon cas, /font/**.ttf) et ajouter cette méthode à votre application. C'est du travail à 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;   }

Si vous souhaitez uniquement utiliser une police à monospace, utilisez la commande "Courier". = > nouvelle police (affichage, "Courrier", 10, SWT.NORMAL)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top