V8.1.0.RC1 Tree set Items as HTML

Hi,

is it possible to say the new Tree that it should its items as HTML elements? Some of the elements in my tree are very long texts (for instnace descriptions), so I was looking for a method to display them in several lines. But it seems that Tree isn’t supporting something like that, so I used a customized ItemCaptionGenerator to wrap these texts into a -tag, but then the Tree is showing something like this text. Then I tried so set the contentmode to HTML but then the Page with the tree couldn’t be loaded.

So, is there a way to say the Tree that it should render the captions of its items as html, or any other method to display its items with multiple lines?

I think multiple lines are not supported… but you can set the com.vaadin.ui.renderers.HtmlRenderer to your column.

Hi Moritz,
thanks for the Tip with the HtmlRender. Now my Tree renders the captions of its items as Html-Elements, but now I’ve some problems with the sizing. I reset the sizing properties of the underlaying TreeGrid to its default, so that it is forced to adapt the sizes to the row’s content, but somehow it has no effect.

My “customized” Tree implementation

 private class HTMLItemTree<T> extends Tree<T>
  {
    public HTMLItemTree(TreeDataProvider<T> provider)
    {
      super(provider);
      @SuppressWarnings ("unchecked")
      TreeGrid<T> grid = (TreeGrid<T>) getCompositionRoot();
      HtmlRenderer renderer = new HtmlRenderer();
      grid.getColumns().forEach(c -> {
        @SuppressWarnings ("unchecked")
        Column<T, String> cs = (Column<T, String>) c;
        cs.setRenderer(renderer);
        cs.setWidthUndefined();
      });

      grid.setRowHeight(-1);
      grid.setWidthUndefined();
    }
  }

And here the implementation of ItemCaptionGenerator[color=#5b7f8b]

    tree.setItemCaptionGenerator(p -> {
      if (p.getFirst().endsWith(SUFFIX_DESC))
      {
        StringBuilder sb = new StringBuilder();
        sb.append("<textarea class=\"v-textarea v-textarea-readonly v-widget v-readonly v-has-width\" wrap=\"hard\" id=\"")
            .append(p.getFirst())
            .append("\" tabindex=\"0\" readonly=\"\" style=\"width: 100%;\">")
            .append(p.getSecond())
            .append("</textarea>");

        return sb.toString();
      }

      return p.getSecond();
    });

What am I missing here?
[/color]

EDIT: Am I correct with the assumption that the Grid (also TreeGrid) cannot handle different different row-dependent height?

Hi,

Vaadin 8 Tree has a ContentMode starting from 8.1.0.beta3. You can tell Tree to show your data as HTML, and you can provide a static row height for all your rows.

//Teemu

Hi Teemu,

I’ve already tried to set the ContentMode to HTML, but when I did that the page became unloadable, say the page froze at 80% or 90% and ran into a timeout. It worked when I a took the underlaying TreeGrid set an HtmlRenderer for “column”.

Anyways, I came to the conclusion that I can not use the Tree for my purpose. The Vaadin 8 Tree is unfortunately not flexiable enough for my needs.

The Tree component is on purpose a simplified version of the TreeGrid. It is intended as the quick to set up for specific tasks alternative. If you have needs of a more complex hierarchical component, you should use TreeGrid directly. The Tree is using a custom theming for the TreeGrid by setting the primary style name to
v-tree8
. You can either keep the Grid-like theming of TreeGrid, or copy what you want from the theme of the Tree.

//Teemu

Maybe it would make sense to upgrade this add-on to Vaadin 8? That would be really flexible for certain use cases.


https://vaadin.com/directory#!addon/componenttree

Upgrading it shouldn’t be too big effort. I prototyped it quickly:

package com.mycompany.myapp;

import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.Resource;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;

public class ComponentTree extends VerticalLayout {

    private final Resource ICON_COLLAPSED = VaadinIcons.CARET_RIGHT;
    private final Resource ICON_EXPANDED = VaadinIcons.CARET_DOWN;

    public ComponentTree() {
        super();
    }

    public ComponentTreeItem addChild(Component c) {
        ComponentTreeItem i = new ComponentTreeItem(c);
        addComponent(i);
        return i;
    }

    public class ComponentTreeItem extends HorizontalLayout implements ClickListener {

        private static final long serialVersionUID = -1436990419814629056L;
        private Button expander;
        private boolean expanded = false;
        private VerticalLayout children;

        public ComponentTreeItem(Component c) {
            super();
            setSpacing(false);
            setMargin(false);
            this.expander = new Button();
            this.expander.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
            this.expander.addStyleName(ValoTheme.BUTTON_LINK);
            this.expander.addStyleName("componenttree-expander");

            this.children = new VerticalLayout();
            this.children.setMargin(new MarginInfo(false, false, false, true));
            this.children.setVisible(false);
            this.children.setStyleName("componenttree-children");

            this.setStyleName("componenttree-child");
            this.addComponent(this.expander);
            VerticalLayout content = new VerticalLayout(c, children);
            content.setMargin(false);
            this.addComponent(content);
        }

        public ComponentTreeItem addChild(Component c) {
            ComponentTreeItem i = new ComponentTreeItem(c);
            this.expander.setIcon(ICON_COLLAPSED);
            this.expander.addClickListener(this);
            this.children.addComponent(i);
            this.setStyleName("componenttree-parent");
            return i;
        }

        public void removeChild(ComponentTreeItem c) {
            this.children.removeComponent(c);
        }

        @Override
        public void buttonClick(ClickEvent event) {
            this.expanded = !this.expanded;
            this.expander.setIcon(this.expanded ? ICON_EXPANDED : ICON_COLLAPSED);
            this.children.setVisible(this.expanded);
        }

    }
}