Domanda

Esiste un modo in SWT per ottenere semplicemente un carattere a spaziatura singola, che funziona su vari sistemi operativi?

Ad esempio. funziona su Linux, ma non su Windows:


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

o devo avere un metodo che prova a caricare vari tipi di carattere (Consolas, Terminal, Monaco, Mono) fino a quando uno non è nullo? In alternativa, potrei specificarlo in un file delle proprietà all'avvio.

Ho provato a ottenere il carattere di sistema da Display, ma non era monospaziato.

È stato utile?

Soluzione

Secondo la sezione File di configurazione dei caratteri nella documentazione JDK di API relative al supporto per l'internazionalizzazione , il concetto di Carattere logico viene utilizzato per definire alcuni caratteri indipendenti dalla piattaforma che sono mappati a caratteri fisici nei file di configurazione dei caratteri predefiniti:

  

La piattaforma Java definisce cinque nomi di font logici che ogni implementazione deve supportare: Serif, SansSerif, Monospaced, Dialog e DialogInput. Questi nomi di caratteri logici sono associati a caratteri fisici in modi dipendenti dall'implementazione.

Quindi, nel tuo caso, proverei

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

per ottenere un handle per il carattere fisico monospaziato della piattaforma corrente su cui è in esecuzione il codice.

Modifica : sembra che SWT non sappia nulla dei caratteri logici ( Bug 48055 su eclipse.org lo descrive in dettaglio). In questo bug report è stata suggerita una soluzione alternativa, in cui il nome del font fisico può essere recuperato da un font AWT ...

Altri suggerimenti

Ho trascorso un po 'a battere la testa contro questo fino a quando ho capito che ovviamente l'eclissi doveva avere accesso a un carattere monospace da usare nei suoi campi di testo, console, ecc. Un po' di scavo alzato:

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

Il che funziona se tutto ciò che ti interessa è acquisire un carattere monospace.

Modifica: O sulla base del commento di @ ctron:

Font font = JFaceResources.getTextFont();

Modifica: Avvertenza (sulla base del commento di @ Lii): questo ti porterà il carattere di testo configurato, che può essere sostituito dall'utente e potrebbe non essere un carattere monospace. Tuttavia, sarà coerente, ad esempio, con il carattere utilizzato nell'editor e nella console che probabilmente è ciò che desideri.

Per quanto ne so, l'API AWT non espone le informazioni sui caratteri sottostanti. Se riesci a raggiungerlo, mi aspetto che dipenda dall'implementazione. Certamente, confrontando i file di mappatura dei font in un paio di directory lib di JRE, posso vedere che non sono definiti in modo coerente.

Potresti caricare i tuoi caratteri, ma sembra un po 'dispendioso dato che sai che la piattaforma viene fornita con ciò di cui hai bisogno.

Questo è un trucco che carica un carattere 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;
}

Funziona su IBM / Win32 / JRE1.4, Sun / Win32 / JRE1.6, Sun / Linux / JRE1.6, ma è un approccio piuttosto fragile. A seconda delle tue esigenze per I18N, potrebbe essere un problema anche lì (non ho controllato).

Un altro trucco sarebbe quello di testare i caratteri disponibili sulla piattaforma:

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

}

Questo probabilmente non è un buon approccio in quanto potrebbe lasciarti esposto a problemi di localizzazione. Inoltre, non sai se il primo carattere a spaziatura fissa che incontri non è un set di icone di avvolgimenti.

L'approccio migliore potrebbe essere quello di fare la tua ipotesi migliore sulla base di una whitelist di mappatura di font / locale e assicurarsi che gli utenti possano facilmente riconfigurare l'interfaccia utente in modo che si adatti a FontDialog .

Per le persone che hanno lo stesso problema, puoi scaricare qualsiasi file ttf di caratteri, metterlo nella cartella delle risorse (nel mio caso / font / * * .ttf) e aggiungere questo metodo al tuo applicazione. Funziona al 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;   }

Se vuoi solo un carattere a spaziatura fissa usa " Courier " = & Gt; new Font (display, " Courier " ;, 10, SWT.NORMAL)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top