How to add child component from other files into main component

I created a new component in a seperate file which is basically a TextButton.Created its object in the main component,did all the resize addAndMake visible staff in the main component but the it doesnt appear at all on the screen as expected.
Here is main new component .h file

class Tremolo  : public juce::Component
{
public:
    Tremolo();
    ~Tremolo() override;

    void paint (juce::Graphics&) override;
    void resized() override;
   void processTremolo(const juce::AudioSourceChannelInfo& bufferToFill);

private:
    enum TremoloState{
        On,Off};
    void changeTremoloState(TremoloState newTremoloState);
    int setTremoloSwitch();
    int sgn(float ph);
    void tremoloButtonClicked();
    //tremolo members
        int notDiv=4;
        double currentSampleRate;
        float phase;
        float inverseSamplerate;
        const int  depth=1;
        int tremSwitch;
        float bpm=100.0;
        double freq=(bpm/60.0)/notDiv;
        TremoloState tremoloState;
    juce::TextButton tremoloButton;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Tremolo)
};

the .cpp
Tremolo::Tremolo():tremoloState(Off)
{
addAndMakeVisible(&tremoloButton);
tremoloButton.setButtonText(“Stutter”);
tremoloButton.onClick=[this]{tremoloButtonClicked();};
tremoloButton.setColour(juce::TextButton::buttonColourId, juce::Colours::transparentBlack);
tremoloButton.setEnabled(false);
// In your constructor, you should add any child components, and
// initialise any special settings that your component needs.

}

Tremolo::~Tremolo()
{
}

void Tremolo::paint (juce::Graphics& g)
{
// /* This demo code just fills the component’s background and
// draws some placeholder text to get you started.
//
// You should replace everything in this method with your own
// drawing code…
// */
//
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
// clear the background

// g.setColour (juce::Colours::grey);
// g.drawRect (getLocalBounds(), 1); // draw an outline around the component
//
// g.setColour (juce::Colours::white);
// g.setFont (14.0f);
// g.drawText (“TremoloEfx”, getLocalBounds(),
// juce::Justification::centred, true); // draw some placeholder text

}

void Tremolo::resized()
{
tremoloButton.setBounds(10, 140, getWidth()-20, 20);
}
void Tremolo::changeTremoloState(TremoloState newTremoloState){
if(tremoloState!=newTremoloState){
tremoloState=newTremoloState;
switch (tremoloState) {
case Off:
tremSwitch=0;
tremoloButton.setColour (juce::TextButton::buttonColourId, juce::Colours::transparentBlack);
tremoloButton.setEnabled(true);
break;
case On:
tremSwitch=1;
tremoloButton.setColour (juce::TextButton::buttonColourId, juce::Colours::skyblue);

            break;
    }
}

}
int Tremolo::setTremoloSwitch(){
if(tremoloState==On){
return 1;
}
else if(tremoloState==Off)
return 0;
}
int Tremolo::sgn(float ph){
if(ph<0.5)
return 1;

else return 0;

}
void Tremolo::tremoloButtonClicked()
{
if (tremoloState==Off) {
changeTremoloState(On);

}
else if(tremoloState==On){
        changeTremoloState(Off);
        
    }

}
void Tremolo::processTremolo(const juce::AudioSourceChannelInfo& bufferToFill){

auto * mainBuffer = bufferToFill.buffer;
       const auto * audioData = mainBuffer->getArrayOfWritePointers();


       auto squareWave= sgn(phase);//square waveform
       tremSwitch= setTremoloSwitch();

       auto modulation=1.0f-(tremSwitch*depth*squareWave);//modulator signal
       const auto pII=M_PI;
       inverseSamplerate=1.0/currentSampleRate;
       for (int i = bufferToFill.startSample; i < bufferToFill.startSample + bufferToFill.numSamples; ++i){

           for (int chan = 0; chan < mainBuffer->getNumChannels(); ++chan){
           audioData[chan][i] *= modulation;
           phase+=freq*inverseSamplerate*2*pII;
           if (phase>=1.0) {
            phase-=1.0;
           }
               
           }
           
       }

}

maincomponent.cpp
i included this : addAndMakeVisible(tremoloEfx);//tremoloEfx is the object
all headers are included.

Hi!

  • Add a unique pointer to a tremolo button in your main component’s header file
  • Include the tremolo header file into your main component, create an instance of the tremolo button there (with std::make_unique) and call addAndMakeVisible() from there.
  • Remove addAndMakeVisible() from the tremolo button’s cpp file.
  • Set the bounds of your button from the main component rather than the tremolo button’s file.

Also, you could have the tremolo button inherit from juce::TextButton rather than juce::Component. That would save you some effort.

Finally, there’s something strange going on with your quoted/formatted code blocks. I suspect that you didn’t correctly include them in the message posting, surrounded by ``` on either side.

Here's a code block

Take care!

Tried but not working.It keeps giving errors.
I also noticed when I Draw a Text in the paint function of the Tremolo class, the text appears instead of the button.
Its as though I have to draw the button in paint which I believe isn’t right.

Looks like you’re making the button invisible by setting its colour to transparentBlack in the constructor and when the tremolo state is off… can you try a non-transparent colour and see if it’s visible then?

The paint is a callback, and the Graphics context is aligned for that specific component. If you call a paint method of different component yourself, the coordinates are still set to the component the system called.

addAndMakeVisible is public, so nothing stops you from adding a component as a child of any other component, as long as you have pointers/references to both.

It is safe in that respect, that juce uses SafePointers to avoid dangling pointers. But your own cocde needs to be written in that safe way too. Thats why I would recommend to have ownership hierarchy parallel to the visibility/painting hierarchy.

i figured something out.Instead of inheriting from Component class I inherited from the TextButton class ,removed the paint function and this worked.
But there is an issue, the text of the button can only be set in the mainComponent class, am guessing even the onClick has to be implemented in the same place.
If this is the case then it will make the code splitting useless for my case since am trying to split the code into seperate files for easy workability.

Also the button color is only “setteable” in the MainComponent class.