Jucy way to show and hide components

I am trying to show and hide some child components (essentially each component is a different screen in an app). Currently I am just storing the child components as member variables of the parents, and calling removeChildComponent() on the component I want to hide and addAndMakeVisible on the one I want to show.

However, i would like to just dynamically instantiate a new component whenever I want to show it, so that it gets completely recreated from scratch (and then completely delete the hidden one). The trouble is I am not too sure how to go about this. Im new to c++ and juce. I figure I need to store a pointer of some sort (maybe a smart pointer?) as a member of the parent (ie Component* currentlyShownComponent) and then create a new component with the new operator and have it point to that whenever I want to show a different screen. Can someone point me in the right direction? I have tried to avoid using new (and pointers really) this whole time so im not too familiar with this

You’ll need to use smart pointers to dynamically create them.

Start simple, do something like add a button to your GUI that spawns something else when clicked and also starts a timer that deletes the thing that was spawned after 5 seconds or something.

struct Comp : Component
{
    Comp() 
    { 
        textButton.onClick = [this]() //can't use this unless you capture it!
        {
             if( this->tb.get() == nullptr ) 
             {
                 //make a new one
                 this->tb = std::make_unique<TextButton>("Click Here!");
                 //give it something to do when you click on it
                 this->tb->onClick = [](){ DBG( "you clicked the hidden button!" ); };
                 //make it visible
                 this->addAndMakeVisible(tb.get());
                 //addAndMakeVisible doesn't always call resized(), so do it manually
                 this->resized();
                 //in 5 seconds, delete 'tb'
                 Timer::callAfterDelay(5 * 1000, [this](){ this->tb.reset(); } );
             }
        };

        addAndMakeVisible(textButton);
    }

    void resized() override 
    {
          textButton.setBounds(10, 10, 200, 50 ); //200px wide, 50px tall
          //if tb exists, stick it 10 px below textButton.
          if( tb.get() != nullptr )
              tb->setBounds( textButton.getBounds().withY(textButton.getBottom() + 10); 
    } 
private:
    std::unique_ptr<TextButton> tb;
    TextButton textButton { "Click me" };
};

Thank you very much! with your example I was able to get it all working the way I want it! The make_unique function was key. II had tried this route before but was trying to use the regular constructor and was getting a strange error. Now that I am using make_unique it works great

Glad to hear it. If you’re new to C++, you really need to get your C++ knowledge up before you try to do some more advanced stuff in JUCE. Otherwise you’ll be stuck looking at weird error messages and asking very basic questions on forums that most people will skip over because the answer is “Learn C++ and your question will answer itself”.

1 Like

Some sidenotes:

The method you usually use is setVisible (shouldBeVisible)

Then there is the TabbedComponent, that manages a set of Components, that are shown mutually. The TabBar can be hidden with setTabBarDepth (0);

I wouldn’t worry too much about the memory footprint of a hidden Component, that is negligible.
If you end up having multiple uique_ptrs, you trade it for the overhead to check everytime, if that component exists (runtime as well as clutter in the code).
But that’s just my 2 pennies.

the tab component with a hidden tab bar would work just fine I think. I will have to look into it