Pregunta

¿Existe alguna forma en SWT de obtener una fuente monoespaciada que funcione en varios sistemas operativos?

Por ejemplo. esto funciona en Linux, pero no en Windows:


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

¿

o necesito tener un método que intente cargar diferentes fuentes (Consolas, Terminal, Mónaco, Mono) hasta que una no sea nula? Alternativamente, podría especificarlo en un archivo de propiedades en el inicio.

Intenté obtener la fuente del sistema de la pantalla, pero no fue monoespaciada.

¿Fue útil?

Solución

De acuerdo con la sección en Archivos de configuración de fuente en la documentación JDK de Soporte de internacionalización - API relacionadas , el concepto de fuentes lógicas se utiliza para definir ciertas fuentes independientes de la plataforma que se asignan a fuentes físicas en los archivos de configuración de fuentes predeterminados:

  

La plataforma Java define cinco nombres de fuentes lógicas que cada implementación debe admitir: Serif, SansSerif, Monospaced, Dialog y DialogInput. Estos nombres de fuentes lógicas se asignan a fuentes físicas en formas dependientes de la implementación.

Así que en tu caso, lo intentaría

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

para obtener un identificador de la fuente monoespaciada física de la plataforma actual en la que se ejecuta el código.

Editar : parece que SWT no sabe nada acerca de las fuentes lógicas ( El error 48055 en eclipse.org describe esto en detalle). En este informe de error, se sugirió una solución pirata, donde el nombre de la fuente física se puede recuperar de una fuente AWT ...

Otros consejos

Pasé un rato golpeando mi cabeza contra esta hasta que me di cuenta de que obviamente eclipse debe tener acceso a una fuente monoespaciada para usarla en sus campos de texto, consola, etc. Apareció un poco de investigación:

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

Lo que funciona si todo lo que te interesa es conseguir una fuente monoespaciada.

Editar: O según el comentario de @ctron:

Font font = JFaceResources.getTextFont();

Editar: Advertencia (basada en el comentario de @ Lii's): esto te dará la fuente de texto configurada, que puede ser anulada por el usuario y no puede ser una fuente monoespaciada. Sin embargo, será coherente con, por ejemplo, la fuente utilizada en el editor y la consola, que es probablemente lo que usted quiere.

Según mi conocimiento, la API de AWT no expone la información de la fuente subyacente. Si puede hacerlo, esperaría que dependiera de la implementación. Ciertamente, al comparar los archivos de asignación de fuentes en un par de directorios lib de JRE, puedo ver que no están definidos de manera consistente.

Podrías cargar tus propias fuentes, pero eso es un desperdicio dado que sabes que la plataforma viene con lo que necesitas.

Este es un hack que carga una fuente 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;
}

Funciona en IBM / Win32 / JRE1.4, Sun / Win32 / JRE1.6, Sun / Linux / JRE1.6, pero es un enfoque bastante frágil. Dependiendo de sus necesidades de I18N, también podría haber problemas allí (no lo he comprobado).

Otro truco sería probar las fuentes disponibles en la plataforma:

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

}

Probablemente este no sea un buen enfoque, ya que puede dejarlo expuesto a problemas de configuración regional. Además, no sabes si la primera fuente monoespaciada con la que te encuentras no es un conjunto de iconos de devanados.

El mejor enfoque puede consistir en hacer su mejor estimación basada en una lista blanca de asignación de fuente / ubicación y asegurarse de que los usuarios puedan reconfigurar fácilmente la interfaz de usuario para que se adapte a ellos mismos a través de FontDialog .

Para las personas que tienen el mismo problema, puede descargar cualquier archivo de fuente ttf, ponerlo en la carpeta de recursos (en mi caso / fuente / * * .ttf) y agregar este método a su solicitud. Es trabajo 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 solo desea una fuente monoespaciada, use " Courier " = > nueva fuente (pantalla, " Courier " ;, 10, SWT.NORMAL)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top