Статьи

JavaFX Совет 32: нужны значки?

мотивация

Я кодирую приложения и библиотеки JavaFX с 2013 года, и их объединяет то, что мне нужно было найти хорошие значки / графику, которые я мог бы использовать для них. Как бывший разработчик Swing, я начал с использования файлов изображений, GIF или PNG. Обычно я бы лицензировал такую ​​библиотеку, как «O-Collection» от IconExperience ( www.incors.com ). Но вскоре мне стало очевидно, что использовать файлы изображений слишком больно.

Представьте себе на мгновение, что вы хотите поддерживать разные псевдо-состояния ваших узлов (например, «зависание», «нажатие», «фокус»). В итоге вы получите разные версии одного и того же значка для каждого штата. Еще больше файлов необходимо, если вы хотите поддерживать разные размеры (маленький, средний, большой) или разрешение экрана (например, «Retina Display» на Mac, 2x значки). В конечном итоге вы попали в ад файла изображения.

Сначала мне было все равно, потому что я начал с разработки фреймворка. В таких проектах, как CalendarFX или FlexGanttFX, требуется очень небольшое количество значков. Поэтому использование файлов PNG для этих библиотек не было проблемой. Но как только я начал работать над большими проектами, необходимость в поддержке сотен иконок стала очевидной.

Иконочные шрифты

К счастью для всех нас, сеть уже придумала решение этой проблемы, и решение называется «Icon Fonts». Большим преимуществом шрифта иконки является тот факт, что все иконки содержатся в одном файле. Это делает управление ими в вашем рабочем пространстве очень простым. Другое преимущество заключается в том, что иконки шрифтов можно стилизовать с помощью CSS. Таким образом, один значок может отображаться в разных цветах и ​​размерах.

Самым популярным значком шрифта, по крайней мере в начале, был FontAwesome, и для него существует реализация JavaFX под названием FontAwesomeFX от Jens Deters. Я использовал эту библиотеку для всех своих проектов в течение очень долгого времени и никогда не думал, что мне нужно что-то еще. Так продолжалось до тех пор, пока я не наткнулся на прекрасную библиотеку Андреса Алмирея «Иконли» Вы можете найти его на GitHub . После этого я использовал его для всей моей работы, связанной с JavaFX. Для моих больших приложений, но и для моих библиотек.

Что мне нравится в Ikonli, так это то, что он легко интегрируется с существующим API JavaFX. Значок — это просто расширение узла «Текст» (дух!), И он имеет настраиваемые свойства. Есть свойства для самой иконки, значка «код», для его цвета и для его размера. Имена этих свойств в файлах CSS также следуют соглашению. Там они называются -fx-icon-code, -fx-icon-color и -fx-icon-size.

интеграция

Ikonli поставляется не только с FontAwesome, но и с 31 (!) Различными шрифтами. Среди них значки дизайна материалов, значки погоды, значки платежей (кредитные карты и т. Д.). Каждый из них поставляется в своем собственном модуле / артефакте и может быть импортирован индивидуально, например, через зависимости Maven. Следующие зависимости необходимо добавить в POM-файл вашего проекта Maven, если вы хотите использовать значок шрифта Material Design .

01
02
03
04
05
06
07
08
09
10
11
12
13
<dependencies>
    <dependency>
        <groupId>org.kordamp.ikonli</groupId>
        <artifactId>ikonli-javafx</artifactId>
        <version>11.3.5</version>
    </dependency>
</dependencies>
 
<dependency>
    <groupId>org.kordamp.ikonli</groupId>
    <artifactId>ikonli-materialdesign-pack</artifactId>
    <version>11.3.5</version>
</dependency>

Шпаргалки

Шрифты значков часто идут с большим количеством значков. Так что найти правильного сложно. Ikonli делает это легко, предоставляя «шпаргалку» для каждого шрифта. Значок для «Material Design» можно увидеть ниже.

кодирование

Создав узел / экземпляр FontIcon, вы можете использовать его в любом месте сцены сцены JavaFX. Ниже вы видите пример установки его на кнопку с помощью кода.

1
2
3
Button button = new Button("User Account");
    button.setGraphic(new FontIcon());
    button.setId("account-button");

Чтобы стилизовать иконку, добавьте в свой файл CSS следующее:

1
2
3
4
5
#account-button .ikonli-font-icon {
    -fx-icon-code: "mdi-account";
    -fx-icon-color: blue;
    -fx-icon-size: 1.2em;
}

Чтобы использовать значок внутри файла FXML, вы можете написать это:

1
2
3
4
5
<Button text="User Account" id="account-button">
  <graphic>
     <FontIcon iconLiteral="mdi-account"/>
  </graphic>
<Button>

Пользовательские Шрифты

Вы также можете создать свой собственный шрифт иконок для JavaFX на основе Ikonli. Очевидно, что первое, что вам нужно, это файл шрифта. Доступно несколько онлайн-сервисов, позволяющих создать такой шрифт. Они позволяют вам выбирать иконки из различных уже существующих шрифтов, но они также позволяют загружать ваши собственные файлы SVG. Тот, который я использовал, называется Fontello. Он имеет три основных области: выбор значков и / или выгрузка, настройка имен, настройка кодов.

После того, как вы правильно настроили свои значки онлайн, вы можете загрузить результат в виде ZIP-файла. Внутри ZIP-файла вы найдете значок шрифта в различных форматах.

Чтобы убедиться, что все ваши иконки на самом деле находятся внутри шрифта, вы можете открыть файл через «Книгу шрифтов» (на Mac). Это должно выглядеть примерно так:

Иконка Enum

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.acme.font;
 
import org.kordamp.ikonli.Ikon;
 
public enum MyIcon implements Ikon {
    HOUSE("my-icon-house", '\ue815'),
    CAR("my-icon-car", '\ue816'),
    DOG("my-icon-dog", '\ue817'),
    CAT("my-icon-cat", '\ue818'),
    KID("my-icon-kid", '\ue819');
 
    private String description;
    private char icon;
 
    MyIcon(String description, char icon) {
        this.description = description;
        this.icon = icon;
    }
 
    public String getDescription() {
        return description;
    }
 
    public char getCode() {
        return icon;
    }
 
    public static MyIcon findByDescription(String description) {
        for (MyIcon icon : values()) {
            if (icon.description.equals(description)) {
                return icon;
            }
        }
        throw new IllegalArgumentException("Icon not supported: " + description);
    }
}

Икон Хэндлер

Следующее, что вы должны реализовать, — это расширение AbstractIkonHandler. В этом примере, где все литералы значков имеют префикс «my-icon», метод «support» возвращает именно этот префикс.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.acme.font;
import org.kordamp.ikonli.AbstractIkonHandler;
import org.kordamp.ikonli.Ikon;
 
public class MyIkonliHandler extends AbstractIkonHandler {
 
    public boolean supports(String description) {
        return description != null && description.startsWith("my-icon-");
    }
 
    public Ikon resolve(String description) {
        return MyIcon.findByDescription(description);
    }
 
    public String getFontResourcePath() {
        return "com/acme/fonts/my-icons.ttf";
    }
 
    public String getFontFamily() {
        return "my-icons";
    }
}

Сервисный поиск

Теперь осталось только сделать шрифт доступным для всего мира. Это делается с помощью поиска службы, что означает, что вам нужно создать файл с именем «org.kordamp.ikonli.IkonHandler» внутри папки META-INF / services. Внутри этого файла вам нужно добавить полное имя класса вашего класса обработчика (com.acme.font.MyIkonliHandler).

пример

На следующем снимке экрана показан модуль шрифта, который мы используем в нашем проекте Maven. Ваш проект должен выглядеть примерно так.

Это оно! Удачного кодирования всем!

Опубликовано на Java Code Geeks с разрешения Дирка Леммермана, партнера нашей программы JCG. Смотрите оригинальную статью здесь: JavaFX Совет 32: Нужны иконки? Используйте Ikonli!

Мнения, высказанные участниками Java Code Geeks, являются их собственными.