Using Icons from Other Font Libraries
To enhance the custom theme, you may need to create icons and embed them into fonts, as well as use any external icons library. As an example, consider using the Font Awesome 5 with the Brands style.
-
Create the enum class implementing the
com.vaadin.server.FontIcon
interface for the new icons: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"); } }
-
Add new styles to the custom theme. We recommend creating special subfolder
fonts
in the main folder of the custom theme, for example,themes/helium-extended/fonts
. Put the styles and font files in their own subfolders, for example,fonts/fontawesome
.Files of fonts are represented by the following extensions:
-
.eot
, -
.svg
, -
.ttf
, -
.woff
, -
.woff2
.
The set of fonts
fontawesome
with the Brands style consists of 5 joint used files:fa-brands-400.eot
,fa-brands-400.svg
,fa-brands-400.ttf
,fa-brands-400.woff
,fa-brands-400.woff2
.If you want to use other styles (Solid, Regular, and so on), you need to define a unique class name for every FontAwesome variant. Also, you need to implement separate
IconSets
andProviders
for every variant. -
-
Create a file with styles that includes
@font-face
and a CSS class with the icon style. Below is an example of thefontawesome5.scss
file, where theFontAwesome5Brands
class name corresponds to the value returned by theFontIcon.getFontFamily()
method:@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; }
-
Create a reference to the file with font styles in
helium-extended.scss
or other files of the custom theme:@import "fonts/fontawesome5/fontawesome5";
-
Then create a new icon set which is an enumeration implementing the
Icons.Icon
interface: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(); } }
-
Create a new
IconProvider
.For managing custom icon sets Jmix framework provides the mechanism that consists of
IconProvider
andIconResolver
.IconProvider
is a marker interface that can provide resources (com.vaadin.server.Resource
) by the icon path.The
IconResolver
bean obtains all beans that implement theIconProvider
interface and iterates over them to find the one that can provide a resource for the icon.To use this mechanism, you should create your implementation of
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); } }
Here we explicitly assign an order for this bean with the
@Order
annotation. -
Register your icon set in the
application.properties
file:jmix.ui.icons-config = ui.ex1.icon.FontAwesome5Icon
Now you can use new icons by direct reference to their class and enum element in the XML descriptor of the screen:
<button icon="font-awesome5-brands-icon:JAVA"/>
or in the Java controller:
cIconBtn.setIconFromSet(FontAwesome5Icon.JAVA);
Overriding Icons with Icon Sets
The mechanism of icon sets enables you to override icons from other sets. To do this, you should create and register a new icon set (enumeration) with the same icons (options) but with different icon paths (source
). In the following example, the new MyIcon
enum is created to override the standard icons from the JmixIcon
set.
-
Create the new icon set:
public enum NewIcon implements Icons.Icon { OK("classpath:/icon/custom-ok.png"); }
-
Register the new icon set in
application.properties
:jmix.ui.icons-config = ui.ex1.icon.NewIcon
Now, the new OK icon will be used instead of the standard one:
@Autowired
private Icons icons;
@Subscribe
protected void onInit(InitEvent event) {
okIconBtn.setIcon(icons.get(JmixIcon.OK));
}
In case you need to ignore redefinitions, you still can use the standard icons by using the icon source instead of the option name:
<button caption="Custom" icon="font-icon:CHECK"/>
or
oIconBtn.setIcon(JmixIcon.OK.source());