Set styling on specific tree item

In a tree component I want to be able to in real time add and remove styling on specific items using its itemId.

I’ve looked through the tree component and searched for similar questions, but In haven’t found anything. Does anyone have an idea of how to achieve this?

“In real time” meaning exactly what?

You can use an ItemStyleGenerator for a Tree, which let’s you add CSS classes to the nodes using item ids:
https://vaadin.com/api/com/vaadin/ui/Tree.ItemStyleGenerator.html

Thanks Jouni!

By “in real time” I really meant “at run time”. There’s a search feature connected to the tree with wildcard capability, and therefore I want items that correspond to the filter parameter should have its label weight set to bold.

I took a quick look at Tree.ItemStyleGenerator previously, but I could only see how you could request/get the style for an item, not setting the style… Do you know of any implementation examples?

The styling I’m adding to an item is being added to all items in the tree. I have a validator that checks the itemId, making sure that only the items that are searched for are supposed to get the styling, even though it’s applied to all items.

This is my code:


Item item = customerTree.getItem(itemId);
String itemName = item.getItemProperty("name").getValue().toString().toLowerCase();
if(itemName.equals(filter))	{
customerTree.setItemStyleGenerator(new treeItemStyleGenerator(itemId, false));
}

private class treeItemStyleGenerator implements Tree.ItemStyleGenerator	{

		public treeItemStyleGenerator(Object itemId, boolean clearStyle)	{
			
			if(!clearStyle)	{
				getStyle(itemId);				
			} else	{
				clearStyle(itemId);
			}
			
		}
		
		@Override
		public String getStyle(Object itemId) {
			// TODO Auto-generated method stub
			return "bold";
		}
		
		public String clearStyle(Object itemId)	{
			return "";
		}
		
	}

CSS:

.v-tree-node-bold {
	font-weight: bold;
	color: #07407F;
}

does anyone see any obvious errors with my code that would explain why the style is added to all items?

Hi Max,

I would have thought (I’ve not used the Tree at all, let alone the ItemStyleGenerator ) that ItemStyleGenerator is set once, and called for every item when it is rendered.

So, I think that you would want to do something more like this (typed in browser, not tested or even compiled!):


customerTree.setItemStyleGenerator(new Tree.ItemStyleGenerator(){
   @Override
    public String getStyle(Object itemId) {
      Item item = customerTree.getItem(itemId);
      String itemName = item.getItemProperty("name").getValue().toString().toLowerCase();
      if(itemName.equals(filter))    {
        return "bold";
      } else {
        return "";
      }
    }
}});

I’m not sure how to get the tree to refresh the style when filter changes - probably force a repaint somehow.

HTH,

Cheers,

Charles.

Echoing Charles, that’s how I see it should work. If not, then either there’s a bug or then we both read the specs wrong.

Thank you Charles!

You were on the right track, no doubt. The problem now is that the child nodes of the node I add the styling to also inherits the same styling…
This is very problematic for me. I tried solving it by adding a clear CSS class with standard styling to the nodes that shouldn’t be affected by the styling. The problem then was that this style was also added to the parent of the node that should be styled, which overrides the styling of the focused node.

It’s a bit of a programmatic dilemma I would say…

Charles did provide the correct approach. The only problem was that every node inside the node that was styled also obtained the same styling.
In addition to what Charles suggested I also had to call a request repaint of the tree for each item in the tree.


if(itemName.equals(filter))	{

customerTree.setItemStyleGenerator(new Tree.ItemStyleGenerator() {
								
								@Override
								public String getStyle(Object itemId) {
									
									Item item = customerTree.getItem(itemId);
									
									String itemName = item.getItemProperty("name").getValue().toString().toLowerCase();
									if(itemName.equals(filter))	{
										return "bold";
									} else	{
										return"clear";
									}
									
								}
							});
							   
							   customerTree.requestRepaint();
}

This will give the styling to an individual item if you find yourself in the same problem!

Hi,
I have the same problem but neither requestPaint (depracated in 7.1) nor markAsDirty can solve it. What can I do?

Greetings
Bernhard

Hi All ,

My Case is somthign different ,

I have more several level of tree , and each lever i have several items then i need to added more then one style to a Item , like base on some logic , the caption of time should be Bold , some item’s need to be strickthrough , bold & strickthrough are not inter related logic.

so how can we achiew this ?

advance thanks