Добавление значков из других библиотек шрифтов
Для более тонкой настройки расширенной темы можно создать значки, встроенные в шрифты, либо использовать готовые внешние библиотеки значков. В качестве примера рассмотрим использование шрифта Font Awesome 5 со стилем Brands.
-
Создайте класс enum, реализующий интерфейс
com.vaadin.server.FontIcon
, в который поместите новые значки:public enum FontAwesome5Brands implements FontIcon { JAVA(0XF4E4); public static final String FONT_FAMILY = "FontAwesome5Brands"; private final int codepoint; FontAwesome5Brands(int codepoint) { this.codepoint = codepoint; } @Override public String getFontFamily() { return FONT_FAMILY; } @Override public int getCodepoint() { return codepoint; } @Override public String getHtml() { return GenericFontIcon.getHtml(FONT_FAMILY, codepoint); } @Override public String getMIMEType() { throw new UnsupportedOperationException(FontIcon.class.getSimpleName() + " should not be used where a MIME type is needed."); } public static FontAwesome5Brands fromCodepoint(final int codepoint) { for (FontAwesome5Brands f : values()) { if (f.getCodepoint() == codepoint) { return f; } } throw new IllegalArgumentException( "Codepoint " + codepoint + " not found in FontAwesome 5"); } }
-
Добавьте новые стили и файлы шрифта в свою тему. Рекомендуется создать отдельную папку
fonts
в главном каталоге расширения темы, например,themes/helium-extended/fonts
. Поместите в нее стили и файлы шрифтов в своих собственных подпапках, например,fonts/fontawesome
.Файлы шрифта включают в себя набор следующих расширений:
-
.eot
, -
.svg
, -
.ttf
, -
.woff
, -
.woff2
.
Набор шрифтов
fontawesome
со стилем Brands представлен в виде 5 файлов:fa-brands-400.eot
,fa-brands-400.svg
,fa-brands-400.ttf
,fa-brands-400.woff
,fa-brands-400.woff2
, которые используются совместно.Если вы хотите использовать другие стили (Solid, Regular и так далее), нужно определить уникальное имя класса для каждого варианта FontAwesome. Также необходимо реализовать отдельные
IconSets
иProviders
для каждого варианта. -
-
Создайте файл стилей, в который включите
@font-face
и CSS класс со стилем для значка. Ниже представлен пример файлаfontawesome5.scss
, где имя классаFontAwesome5Brands
соответствует значению, возвращаемому методомFontIcon.getFontFamily()
:@mixin font-icon-style { speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* FontAwesome 5 Brands */ @mixin font-awesome-5-brands-style { font-family: 'FontAwesome5Brands'; @include font-icon-style; } @font-face { font-family: 'FontAwesome5Brands'; src: url('fa-brands-400.eot?hwgbks'); src: url('fa-brands-400.eot?hwgbks#iefix') format('embedded-opentype'), url('fa-brands-400.ttf?hwgbks') format('truetype'), url('fa-brands-400.woff?hwgbks') format('woff'), url('fa-brands-400.svg?hwgbks#icomoon') format('svg'); font-weight: normal; font-style: normal; } .FontAwesome5Brands { @include font-awesome-5-brands-style; }
-
Подключите файл стилей шрифта в
helium-extended.scss
или другой файл данной темы:@import "fonts/fontawesome5/fontawesome5";
-
Затем создайте новый набор значков, то есть enum, реализующий интерфейс
Icons.Icon
:public enum FontAwesome5Icon implements Icons.Icon { JAVA("font-awesome5-brands-icon:JAVA"); protected String source; FontAwesome5Icon(String source) { this.source = source; } @Override public String source() { return source; } @Override public String iconName() { return name(); } }
-
Создайте новый
IconProvider
.Для работы с наборами значков в фреймворке Jmix есть механизм, основанный на использовании
IconProvider
иIconResolver
.IconProvider
– это интерфейс-маркер, который предоставляет доступ к ресурсу (com.vaadin.server.Resource
) по переданному пути.Бин
IconResolver
проходится по всем бинам, реализующимIconProvider
, в поисках того, кто может предоставить ресурс к данному значку.Чтобы использовать этот механизм, необходимо создать собственную реализацию
IconProvider
, например, так:@Order(10) @Component("sample_FontAwesome5BrandsIconProvider") public class FontAwesome5BrandsIconProvider implements IconProvider { public static final String FONT_AWESOME_5_BRANDS_PREFIX = "font-awesome5-brands-icon:"; private final Logger log = LoggerFactory.getLogger(FontAwesome5BrandsIconProvider.class); @Override public Resource getIconResource(String iconPath) { Resource resource = null; iconPath = iconPath.split(":")[1]; try { resource = ((Resource) FontAwesome5Brands.class .getDeclaredField(iconPath) .get(null)); } catch (IllegalAccessException | NoSuchFieldException e) { log.warn("There is no icon with name {} in the FontAwesome5Brands icon set", iconPath); } return resource; } @Override public boolean canProvide(String iconPath) { return !Strings.isNullOrEmpty(iconPath) && iconPath.startsWith(FONT_AWESOME_5_BRANDS_PREFIX); } }
Здесь мы явно назначаем порядок для этого бина аннотацией
@Order
. -
Далее нужно зарегистрировать набор значков в файле
application.properties
:jmix.ui.icons-config = ui.ex1.icon.FontAwesome5Icon
Теперь вы можете использовать значки по прямой ссылке на класс и элемент enum в XML-дескрипторе экрана:
<button icon="font-awesome5-brands-icon:JAVA"/>
или в контроллере Java:
cIconBtn.setIconFromSet(FontAwesome5Icon.JAVA);
Переопределение значков с помощью наборов
Механизм наборов значков позволяет переопределять некоторые значки из других наборов. Для этого необходимо создать и зарегистрировать новый набор значков (enumeration) с теми же именами значков (options), но с другими путями (source
). В примере ниже создан новый набор MyIcon
, в котором переопределены стандартные значки из набора JmixIcon
.
-
Создайте новый набор значков:
public enum NewIcon implements Icons.Icon { OK("classpath:/icon/custom-ok.png"); }
-
Зарегистрируйте новый набор значков в
application.properties
:jmix.ui.icons-config = ui.ex1.icon.NewIcon
Теперь вместо стандартного значка OK будет использован новый:
@Autowired
private Icons icons;
@Subscribe
protected void onInit(InitEvent event) {
okIconBtn.setIcon(icons.get(JmixIcon.OK));
}
При необходимости игнорировать переопределение и использовать стандартные значки, просто используйте путь к значку вместо имени элемента перечисления:
<button caption="Custom" icon="font-icon:CHECK"/>
или
oIconBtn.setIcon(JmixIcon.OK.source());