How to capture TabbedComponent's tab active


#1

Hi all,
I used a component inherited from TabbedComponent to show tabs.
At the init time, I added tabs
void init()
{

m_tabs->addTab(“tab-name-1”, tab-color-1, new myComponentA(), true);
m_tabs->addTab(“tab-name-2”, tab-color-2, new myComponentB(), true);
addAndMakeVisible(m_tabs);

}

After initialized, my UI already had 2 tabs with the content of myComponentA,
myComponentB and it didn’t reload again when I clicked to tab1 or tab2.

How can I detect tab1 or tab2 click event to reload UI, because in tab2 I change some value in tab1 and I need to reload it?


#2

I think you should get a callback Component::visibilityChanged() in your displayed component, that you can override to update your values.

Hope that helps.


#3

Thank you so much @daniel you your quickly support :slight_smile: I’m going to try it now


#4

Hi @daniel, visibilityChanged() of all component will be called, so all component will be repainted. Can you tell me how to repaint only one tab which is clicked by user?

One more @daniel, How to do if at init time, my app only init tab1 (because it will show tab1 fisrt, and initialize tab2 will take some time) and tab2 is empty that time, then user click to tab2, tab2 will begin draw its UI.


#5

Just check Component::isVisible() in your visibilityChanged() method, it should only be true for the one component, that is currently shown.

When you add the component to the tab, it should only be created, not being painted.

The question is really, what makes the construction that heavy, that you think you have to optimise that away. The update is already moved to visibilityChanged() now.

Doing the creation on a background thread is a bad idea, since creating Components and adding them to the components hierarchy needs to happen on the message thread.


#6

That’s really good support. Thank you so much @daniel


#7

Why not override TabbedComponent::currentTabChanged() ?

Rail


#8

Because then you code things in an unrelated structure. The Component has the knowledge and access to all necessary functions to update itself (since it was implemented in the constructor before, judging by the information in the OP).

But yes, good addition, maybe this callback is useful for somebody.


#9

Hi @daniel, I want to ask one more thing, when I use this code

void init()
{
…
m_tabs->addTab(“tab-name-1”, tab-color-1, new myComponentA(), true);
m_tabs->addTab(“tab-name-2”, tab-color-2, new myComponentB(), true);
addAndMakeVisible(m_tabs);
…
}

At the first time my app run, myComponentA::visibilityChanged() was called and isVisible() is always true

void myComponentA::visibilityChanged()
{
	if (isVisible()) {
           // This code always runs even I clicked tab 'tab-name-2' first
    }
}

After some debug, I found that the code

m_tabs->addTab(“tab-name-1”, tab-color-1, new myComponentA(), true);

called this code

if (currentTabIndex < 0)
            setCurrentTabIndex (0);

in void TabbedButtonBar::addTab (const String& tabName, Colour tabBackgroundColour, int insertIndex)
The problem is setCurrentTabIndex (0); always run at the first time, so tab1 always has isVisible() == true. How to solve it if I want to init tab2 first if user clicked to tab-2 first?


#10

Yes, the ComponentA will be set visible, when it is added as the first tab. You can call setCurrentTabIndex (1, sendChangeMessage); to select the second tab. The first one will be automatically set invisible then.

void init()
{
    //…
    m_tabs->addTab(“tab-name-1”, tab-color-1, new myComponentA(), true);
    m_tabs->addTab(“tab-name-2”, tab-color-2, new myComponentB(), true);
    m_tabs->setCurrentTabIndex (1);
    addAndMakeVisible(m_tabs);
    //…
}

You can get around that problem, if you test Component::isShowing() instead of isVisible. since you call addAndMakeVisible after adding the tabs, isShowing() will return false, if one of the parents is not visible.

But be aware, that you might just move the problem. You will likely miss the actual visibilityChanged, since it is not called, when the parent becomes visible.


#11

Thank you @daniel, I got it and I’ve added a new variable to control if the first tab is first time init.