Pergunta

Existe uma maneira em SWT para obter uma Fonte Monoespaçada simplesmente, que funciona em vários sistemas operacionais?

Por exemplo. Isso funciona em Linux, mas não o Windows:


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

ou eu preciso ter um método que tenta carregar fontes variadas (Consolas, terminais, Mónaco, Mono) até que um não é nulo? Como alternativa eu ??poderia especificá-lo em um arquivo de propriedades na inicialização.

Eu tentei obter a fonte do sistema de Display, mas que não foi monoespaçada.

Foi útil?

Solução

De acordo com a seção sobre Font arquivos de configuração na documentação JDK de APIs relacionados com , o conceito de Logical Fonte s é usado para definir determinadas fontes independentes de plataforma que são mapeadas para fontes físicas nos arquivos de configuração de fonte padrão:

A Plataforma Java define cinco nomes de fonte lógico que cada implementação deve apoiar: Serif, SansSerif, Monospaced, de diálogo, e DialogInput. Estes nomes de fontes lógicas são mapeadas para fontes físicas de maneiras dependentes de implementação.

Assim, no seu caso, eu tentaria

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

para obter um identificador para a fonte monoespaçada física da plataforma atual o código está sendo executado.

Editar : Parece que SWT não sabe nada sobre fontes lógicas ( Bug 48055 em eclipse.org descreve isso em detalhes). Neste relatório de bug uma solução hackish foi sugerido, onde o nome da fonte física podem ser recuperados a partir de um AWT fonte ...

Outras dicas

Eu passei um tempo batendo a cabeça contra este até que eu percebi que, obviamente, eclipse deve ter acesso a uma fonte monoespaçada para uso em seus campos de texto, consolar etc. Um pouco de escavação virou-se:

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

Que funciona se tudo que você está em interessado é se apoderar de alguma fonte monoespaçada.

Editar: ou com base em @ de ctron comentário:

Font font = JFaceResources.getTextFont();

Editar: Aviso (baseado em @ o comentário de LII): isso vai te o texto configurado Font, que pode ser substituído pelo usuário e pode não ser uma fonte monoespaçada. No entanto, será consistente com, por exemplo, a fonte usada no editor e consola que é provavelmente o que você quer.

Para o melhor de meu conhecimento, a API AWT não expõe subjacente informações da fonte. Se você pode obtê-lo, eu esperaria que ele seja dependente da implementação. Certamente, comparando os arquivos de mapeamento da fonte em um par de diretórios do JRE lib, eu posso ver que eles não são definidos de forma consistente.

Você pode carregar suas próprias fontes, mas que parece um pouco desperdício dada você sabe a plataforma vem com o que você precisa.

Este é um hack que carrega uma fonte 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;
}

Ele funciona em IBM / Win32 / JRE1.4, Sun / Win32 / JRE1.6, Sun / Linux / JRE1.6, mas é uma abordagem muito frágil. Dependendo de suas necessidades para I18N, poderia haver problemas lá também (Eu não tenho verificado).

Outro truque seria testar as fontes disponíveis na 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();
        }
    }

}

Esta provavelmente não é uma boa abordagem, uma vez que pode deixá-lo exposto a problemas de localidade. Além disso, você não sabe se a primeira fonte monoespaçada você se deparar não é alguns enrolamentos conjunto de ícones.

A melhor abordagem pode ser apenas para tomar o seu melhor palpite baseado em uma fonte de mapeamento / locale whitelist e certifique-se de que os usuários podem facilmente reconfigurar a interface do usuário para se adequar-se através de FontDialog .

Para as pessoas que têm o mesmo problema, você pode baixar qualquer arquivo TTF fonte, colocá-lo na pasta de recursos (no meu caso /font/**.ttf) e adicione methode para o seu inscrição. É um trabalho 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 você quer apenas um uso da fonte Monospaced "Courier" => new Font(display, "Courier", 10, SWT.NORMAL)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top