Change color of tab caption with java code?

Hi:

My users have asked me to indicate different types of tabs in a tabsheet with different caption colors. I can’t find a way to set the style of the caption of a tab with Java.

setStyleName() on a tab sets the style for the entire tab, not the caption.

I could change the style of ALL tab captions with CSS, but that won’t solve the problem.

Any suggestions?

I managed to get something to work, but there has to be a better way! Does anybody know how? In any event, here’s what worked for me:

First, the CSS:

  .v-tabsheet-tabitemcell-new-order-tabstyle {
    .v-caption .v-captiontext {
      background-color: green;
      color: white;
    }
  }

Next, the Java code:

    @Subscribe
    public void onAfterShow(AfterShowEvent event) {
        if (this.ordnum == null) {
            com.vaadin.ui.TabSheet.Tab tab = findTab(this.getWindow().unwrap(com.vaadin.ui.Component.class));
            if (tab != null) {
                tab.setStyleName("new-order-tabstyle");
            }
        }
    }

    
    protected com.vaadin.ui.TabSheet.Tab findTab(com.vaadin.ui.Component component) {
        if (component.isAttached()) {
            com.vaadin.ui.Component parent = component;
            while (parent != null) {
                if (parent.getParent() instanceof com.vaadin.ui.TabSheet) {
                    return ((com.vaadin.ui.TabSheet) parent.getParent()).getTab(parent);
                }

                parent = parent.getParent();
            }
        }
        return null;
    }

I copied the findTab() routine from the Cuba’s WebTabWindow.java. It is protected, so I couldn’t call it directly.

To do this, I had to unwrap the Vaadin tab component from the Cuba component. There is a setStyleName method on the Vaadin tab that does what I want, but that method is not accessible from Cuba. Finding the Vaadin tab component was a bit difficult, it turns out.

The result:

image

I think this might be a good enhancement candidate. Give us access to style the caption, please?

1 Like

Hi, @ericraskin

Unfortunately, the platform does not have public methods for getting a tab from the main tabsheet. Therefore, your method is a good workaround to solve this problem.
But if you add a TabSheet component inside any screen, then you can set styles to the TabSheet component and any Tab. There are two ways:

  1. Using a XML descriptor
<tabSheet id="tabSheet" stylename="tabsheet-style">
                <tab id="tab1" spacing="true" stylename="tab-style"/>
</tabSheet>
  1. Using Java API
tabSheet.setStyleName("tabsheet-style");
tabSheet.getTab("tab1").setStyleName("tab-style");

Regards,
Gleb

It can’t be done in the XML because it is dependent on the value (only for New Orders).
I did try your Java approach originally, but I found that the style got placed on the contents of the tab and not on the caption. However, I will try again because your solution is much simpler than mine.

In your solution, “tab-style” is the second part of the CSS and appended to the class of the caption, right? In my case, if I call

tabSheet.getTab("Tab1").setStyleName("new-order-style");

I have to set the CSS name as:

.v-tabsheet-tabitemcell-new-order-style

Correct?

Hi, @ericraskin!

If you want to set the style for the Tabsheet then use this code:

tabSheet.setStyleName("tabsheet-style");

And you will get the selector:

.v-tabsheet-tabsheet-style

If you want to set the style for the Tab then use this code:

tabSheet.getTab("Tab1").setStyleName("new-order-style");

And you will get the selector:

.v-tabsheet-tabitemcell-new-order-style

If you want to set the style for the content of the Tab then use this code:

  • XML descriptor
        <tabSheet id="tabSheet">
            <tab id="tab1"/>
        </tabSheet>
  • Controller
   @Named("tabSheet.tab1")
   private VBoxLayout tab1;

   @Subscribe
   public void onInit(InitEvent event) {
       tab1.setStyleName("new-order-style");
   }

And you will get the selector:

.v-tabsheet-content .v-verticallayout-new-order-style

Regards,
Gleb

3 Likes

Hello Gelb,

first of all, thanks for the advice, i am stumbling over a similar task: I want to have the capation of a Tab shown bold under given conditions. I thought of setting the StyleName in my Controller, whenever the condition is met.
My issue is, that the HTML table cell “<td … >” gets the selector set (Perfect!!), but the font weight is set by the “<div class=“v-capation”…>” selector.
Since div is the more inner object, it will override the font-weight style i set on the table cell td.

What is your idea to get around this?

Thanks and best regards
Daniel