3.5.9.2. Using Icons from Other Font Libraries
To enhance the theme extension, you may need to create icons and embed them into fonts, as well as use any external icons library.
-
In the web module create the
enum
class implementingcom.vaadin.server.FontIcon
interface for the new icons:import com.vaadin.server.FontIcon; import com.vaadin.server.GenericFontIcon; public enum IcoMoon implements FontIcon { HEADPHONES(0XE900), SPINNER(0XE905); public static final String FONT_FAMILY = "IcoMoon"; private int codepoint; IcoMoon(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 IcoMoon fromCodepoint(final int codepoint) { for (IcoMoon f : values()) { if (f.getCodepoint() == codepoint) { return f; } } throw new IllegalArgumentException("Codepoint " + codepoint + " not found in IcoMoon"); } }
-
Add new styles to the theme extension. We recommend creating a special subfolder
fonts
in the main folder of theme extension, for example,modules/web/themes/halo/com.company.demo/fonts
. Put the styles and font files in their own subfolders, for example,fonts/icomoon
.Files of fonts are represented by the following extensions:
-
.eot
, -
.svg
, -
.ttf
, -
.woff
.The set of fonts
icomoon
from an open library, used in this example, consists of 4 joint used files:icomoon.eot
,icomoon.svg
,icomoon.ttf
,icomoon.woff
.
-
-
Create a file with styles that includes
@font-face
and a CSS class with the icon style. Below is an example of theicomoon.scss
file, whereIcoMoon
class name corresponds to the value returned byFontIcon#getFontFamily
method:@mixin icomoon-style { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomoon' !important; 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; } @font-face { font-family: 'icomoon'; src:url('icomoon.eot?hwgbks'); src:url('icomoon.eot?hwgbks#iefix') format('embedded-opentype'), url('icomoon.ttf?hwgbks') format('truetype'), url('icomoon.woff?hwgbks') format('woff'), url('icomoon.svg?hwgbks#icomoon') format('svg'); font-weight: normal; font-style: normal; } .IcoMoon { @include icomoon-style; }
-
Create a reference to the file with font styles in
halo-ext.scss
or other file of theme extension:@import "fonts/icomoon/icomoon";
-
Then create new icon set which is an enumeration implementing the
Icons.Icon
interface:import com.haulmont.cuba.gui.icons.Icons; public enum IcoMoonIcon implements Icons.Icon { HEADPHONES("ico-moon:HEADPHONES"), SPINNER("ico-moon:SPINNER"); protected String source; IcoMoonIcon(String source) { this.source = source; } @Override public String source() { return source; } @Override public String iconName() { return name(); } }
-
Create new
IconProvider
.For managing custom icon sets CUBA platform provides the mechanism that consists of
IconProvider
andIconResolver
.IconProvider
is a marker interface that exists only in the web module and can provide resources (com.vaadin.server.Resource
) by the icon path.The
IconResolver
bean obtains all beans that implementIconProvider
interface and iterates over them to find the one that can provide a resource for the icon.In order to use this mechanism, you should create your implementation of
IconProvider
:import com.haulmont.cuba.web.gui.icons.IconProvider; import com.vaadin.server.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Order(10) @Component public class IcoMoonIconProvider implements IconProvider { private final Logger log = LoggerFactory.getLogger(IcoMoonIconProvider.class); @Override public Resource getIconResource(String iconPath) { Resource resource = null; iconPath = iconPath.split(":")[1]; try { resource = ((Resource) IcoMoon.class .getDeclaredField(iconPath) .get(null)); } catch (IllegalAccessException | NoSuchFieldException e) { log.warn("There is no icon with name {} in the FontAwesome icon set", iconPath); } return resource; } @Override public boolean canProvide(String iconPath) { return iconPath.startsWith("ico-moon:"); } }
Here we explicitly assign order for this bean with
@Order annotation
. -
Register your icon set in the application properties file:
cuba.iconsConfig = +com.company.demo.gui.icons.IcoMoonIcon
Now you can use new icons by direct reference to their class and enum
element in XML-descriptor of the screen:
<button caption="Headphones" icon="ico-moon:HEADPHONES"/>
or in the Java controller:
spinnerBtn.setIconFromSet(IcoMoonIcon.SPINNER);
As a result, new icons are added to the buttons:
- Overriding icons with icon sets
-
The mechanism of icon sets enables you to override icons from other sets. In order 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 newMyIcon
enum is created to override the standard icons fromCubaIcon
set.-
The default icon set:
public enum CubaIcon implements Icons.Icon { OK("font-icon:CHECK"), CANCEL("font-icon:BAN"), ... }
-
The new icon set:
public enum MyIcon implements Icons.Icon { OK("icons/my-custom-ok.png"), ... }
-
Register the new icon set in
web-app.properties
:cuba.iconsConfig = +com.company.demo.gui.icons.MyIcon
Now, the new OK icon will be used instead of the standard one:
Icons icons = AppBeans.get(Icons.NAME); button.setIcon(icons.getIcon(CubaIcon.OK))
In case you need to ignore redefinitions, you still can use the standard icons by using the path to an icon instead of the option name:
<button caption="Created" icon="icons/create.png"/>
or
button.setIcon(CubaIcon.CREATE_ACTION.source());
-