Search code examples
vaadinvaadin7

How to set custom font icon when using a Vaadin declarative UI?


I am using a custom font icon set as described at the wiki article Font icons in Vaadin 7.2. Everything works fine.

However, if I use the declarative UI I am not able to get it working.

This is my code so far:

<vaadin-panel caption="..." style-name="..." icon="fonticon://IcoCustom/58884" size-full>

UPDATE

Allowed syntax:

  • font://INDUSTRY (deprecated syntax, assumes FontAwesome font icon)
  • fonticon://FontAwesome/f275 (font family/codepoint in hex. decimal values not allowed)
  • fonticon://MyFonticon/e900 (for setup custom font icons see @Morfic's answer)

Does not work:

  • fonticon://INDUSTRY
  • fonticon://FontAwesome/INDUSTRY

Solution

  • Note: Tested on Vaadin 7.7.3

    1) Went to icomoon as suggested in the Using font-icons wiki article and selected only 1 icon, home (Notice the assigned code e900, that's what we'll use later.):

    icomoon

    2) Copied the fonts folder content as per the same tutorial, but renamed all the files to myfont*: theme font setup

    3) Created the theme files. Notice that there is a discrepancy between the wiki article, and the Vaadin docs theme-font section regarding the @import path, the correct being the one from the docs:

    • wiki [wrong]: @include font(IcoMoon, '../../fonticondemo/fonts/icomoon');
    • docs [right]: @include font(MyFontFamily, '../../../../mytheme/fonts/myfontfamily');

    styles.scss

    @import "mytheme.scss";
    
    @include font(myfont, '../../../../mytheme/fonts/myfont');
    
    /* This file prefixes all rules with the theme name to avoid causing conflicts with other themes. */
    /* The actual styles should be defined in mytheme.scss */
    .mytheme {
      @include mytheme;
    }
    

    mytheme.scss

    @import "../valo/valo";
    
    @mixin mytheme {
      @include valo;
    }
    

    3) Then created the design file and component, nothing fancy, just a layout with a button:

    java

    @DesignRoot
    public class MyDeclarativeComponent extends VerticalLayout {
        public MyDeclarativeComponent() {
            Design.read(this);
        }
    }
    

    html (notice the e900 code used)

    <!DOCTYPE html>
    <html>
        <body>
            <com_example_declarative_font-my-declarative-component>
                <vaadin-button icon="fonticon://myfont/e900" plain-text>My button</vaadin-button>
            </com_example_declarative_font-my-declarative-component>
        </body>
    </html>
    

    4) Optional enum, shamelessly copied from the Vaadin implementation of FontAwesome

    public enum MyFont implements FontIcon {
        HOME(0xe900);
    
        public static final String FONT_FAMILY = "myfont";
        private int codepoint;
    
        private MyFont(int codepoint) {
            this.codepoint = codepoint;
        }
    
        public String getMIMEType() {
            throw new UnsupportedOperationException(FontIcon.class.getSimpleName() + " should not be used where a MIME type is needed.");
        }
    
        public String getFontFamily() {
            return FONT_FAMILY;
        }
    
        public int getCodepoint() {
            return this.codepoint;
        }
    
        public String getHtml() {
            return GenericFontIcon.getHtml(FONT_FAMILY, this.codepoint);
        }
    
        public static MyFont fromCodepoint(final int codepoint) {
            for (MyFont f : values()) {
                if (f.getCodepoint() == codepoint) {
                    return f;
                }
            }
            throw new IllegalArgumentException("Codepoint " + codepoint + " not found in FontAwesome");
        }
    }
    

    5) And a basic UI implementation:

    @Theme("mytheme")
    @PreserveOnRefresh
    @SpringUI(path = "/")
    @Title("Vaadin demo app")
    public class MyUi extends UI {
    
        @Override
        protected void init(VaadinRequest request) {
            Layout content = new VerticalLayout();
            content.setSizeFull();
            setContent(content);
            content.addComponent(new MyDeclarativeComponent());
        }
    }
    

    6) Result:

    result

    7) Bonus - printing declarative format for a component: you can to this in at least 2 simple ways

    a) Design.write(this, System.out);

    b) Vaadin debug mode - use the included tool to print the design to your console vaadin debug mode