2008-10-21 2 views
27

Есть ли способ в SWT, чтобы получить моноширинный шрифт просто, который работает в разных операционных системах?SWT - OS агностический способ получить моноширинный шрифт

Например. это работает на Linux, но не для Windows:

 

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

или мне нужно иметь метод, который не пытается погрузочных изменения шрифтов (Consolas, Terminal, Монако, Mono), пока один не равно нулю? В качестве альтернативы я могу указать его в файле свойств при запуске.

Я попытался получить системный шрифт с дисплея, но это не было моноширинным.

ответ

15

Согласно разделу по Font Configuration Files в документации JDK из Internationalization Support API, о связанных концепции Logical Font s используется для определения некоторых независимые от платформы шрифты, которые отображаются в физические шрифты в файлах конфигурации шрифтов по умолчанию:

Платформа Java определяет пять логических имен шрифтов, которые должны поддерживать каждая реализация: Serif, SansSerif, Monospaced, Dialog и DialogInput. Эти логические имена шрифтов сопоставляются с физическими шрифтами в зависимых от реализации способах.

Так что в вашем случае, я хотел бы попробовать

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

, чтобы получить дескриптор физического моноширинный шрифт текущей платформы ваш код работает.

Редактировать: Кажется, что SWT ничего не знает о логических шрифтах (Bug 48055 на eclipse.org подробно описывает это). В этом сообщении об ошибке было предложено хакерское обходное решение, в котором имя физического шрифта можно получить из шрифта AWT ...

+3

Это должно также быть доступны как java.awt.Font.MONOSPACED – nos 2011-10-08 21:48:33

+0

кажется они обеспечивают класс [SWTFontUtils] (https://bugs.eclipse.org/bugs/attachment.cgi?id=238603) для этого сейчас. – Campa 2015-07-20 07:12:49

4

Насколько я знаю, AWT API не предоставляет основную информацию об шрифте. Если вы можете добраться до него, я ожидаю, что он будет зависимым от реализации. Конечно, сравнивая файлы сопоставления шрифтов в нескольких каталогах JRE lib, я вижу, что они не определены согласованным образом.

Вы можете загрузить свои собственные шрифты, но это кажется немного расточительным, если вы знаете, что платформа поставляется с тем, что вам нужно.

Это хак, который загружает шрифт 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; 
} 

Он работает на IBM/Win32/JRE1.4, Sun/Win32/JRE1.6, Sun/Linux/JRE1.6, но довольно хрупкий подход. В зависимости от ваших потребностей в I18N, это может быть проблемой там (я не проверял).

Другой хак будет проверить шрифты, доступными на платформе:

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

} 

Это, вероятно, не хороший подход, поскольку он может оставить вас подвергается воздействию локалите вопросы. Кроме того, вы не знаете, есть ли первый моноширинный шрифт, с которым вы сталкиваетесь, - это не набор иконок для обмоток.

Наилучший подход может состоять только в том, чтобы наилучшим образом угадать, основываясь на белом списке отображения шрифтов и локалей, и убедитесь, что пользователи могут легко перенастроить пользовательский интерфейс, чтобы удовлетворить себя через FontDialog.

+0

Спасибо за подробный ответ. Я считаю, что лучший вариант, как вы говорите, - конкретный мягкий дефолт, такой как Courier, который доступен на всех платформах, и позволяет пользователю изменять это свойство с помощью диалога настройки шрифта. – JeeBee 2008-10-24 12:07:17

+0

Есть ли способ загрузить «Шрифт» из ресурса Java или «InputStream», а не путь к файлу в SWT? – parxier 2010-04-22 04:41:35

1

Если вы хотите просто моноширинное использование шрифта «Courier» =>new Font(display, "Courier", 10, SWT.NORMAL)

35

Я провел некоторое время, колотить голову об этом других, пока я не понял, что, очевидно, затмит должна иметь доступ к моноширинному шрифту для использования в тексте поля, консоль и т.п. немного покопаться оказалось:

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

Который работает, если все вы заинтересованы в получает владение какого моноширинного шрифта.

Edit: Или на основе комментариев @ ctron в:

Font font = JFaceResources.getTextFont(); 
3

Для людей, которые имеют те же проблемы, вы можете загрузить любой файл TTF шрифта, поместите его в папке ресурсов (в моем случае/шрифте/* * .ttf) и добавьте этот метод в ваше приложение. Он работает 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; } 
Смежные вопросы