How to use Parent and child components in vst3 project

I’m new to juce, here’s a project where I need to add several controls at a time, I think Parent and child components is meet my needs. But I don’t know how to use it in vst3 project. Please help me for that, appreciate that. My current usage is like below shows,But when loading the compiled vst3 in reaper, none of the controls display on vst interface. :

Editor.h:

class LayerComponent : juce::Component
{
public:
    LayerComponent()
    {
        'addAndMakeVisible(colourlabels);
        'addAndMakeVisible(layerlabels);
        'addAndMakeVisible(layersolobuttons);
        'addAndMakeVisible(layermutebuttons);
        'addAndMakeVisible(layertransposetexteditors);
    }

    ~LayerComponent();

    void paint(juce::Graphics& g) override
    {
        // 获取父控件的边界
        juce::Rectangle<int> bounds = getLocalBounds();

        // 设置方形的颜色和渐变
        juce::Colour color1(0xff000000); // 黑色
        juce::Colour color2(0xffffffff); // 白色
        juce::ColourGradient gradient(color1, bounds.getTopLeft().toFloat(), color2, bounds.getBottomRight().toFloat(), false);

        // 绘制方形的背景
        g.setGradientFill(gradient);
        g.fillRoundedRectangle(bounds.toFloat(), 10.0f);

        // 绘制方形的边框
        g.setColour(juce::Colours::black);
        g.drawRoundedRectangle(bounds.toFloat(), 10.0f, 2.0f);
    }
    void resized() override
    {
        
   }
   void setBounds(int x, int y, int width, int height)
    '{
        // 按顺序控件的width的占整个Comnent的width的比率
        int cw = 0.06; int lw = 0.1;int sbw = 0.5;int mbw = 0.1;int tew = 0.1;
        // 从第二个控件开始按顺序控件的x坐标
        int lx = x + (width * cw) + 5;
        int sbx = lx + (width * lw) + 5;
        int mbx = sbx + (width * sbw) + 5;
        int tex = mbx + (width * mbw);


        colourlabels.setBounds(x, y, width * cw, height);
        layerlabels.setBounds(lx, y, width * lw, height);
        layersolobuttons.setBounds(sbx, y, width * sbw, height);
        layermutebuttons.setBounds(mbx, y, width * mbw, height);
        layertransposetexteditors.setBounds(tex, y, width * tew, height);

        colourlabels.repaint();
        layerlabels.repaint();
        layersolobuttons.repaint();
        layermutebuttons.repaint();
        layertransposetexteditors.repaint();
    }
    void setText(juce::String& layerLabelText, juce::String& soloButtonText, juce::String& muteButtonText, juce::String& transposeEditorText)
    {
        layerlabels.setText(layerLabelText, juce::dontSendNotification);
        layersolobuttons.setButtonText(soloButtonText);
        layermutebuttons.setButtonText(muteButtonText);
        layertransposetexteditors.setText(transposeEditorText, juce::dontSendNotification);
    }
    void setColor()
    {
        colourlabels.setColour(juce::Label::textColourId, juce::Colours::blue);

        layerlabels.setFont(juce::Font(15));
        layerlabels.setColour(juce::Label::textColourId, juce::Colours::white);
        layerlabels.repaint();

        layersolobuttons.setColour(juce::TextButton::textColourOffId, juce::Colours::slategrey);
        layersolobuttons.setColour(juce::TextButton::textColourOnId, juce::Colours::white);
        layersolobuttons.setColour(juce::TextButton::buttonColourId, juce::Colours::whitesmoke);
        layersolobuttons.setColour(juce::TextButton::buttonOnColourId, juce::Colours::gold);
        layersolobuttons.repaint();

        layermutebuttons.setColour(juce::TextButton::textColourOffId, juce::Colours::red);
        layermutebuttons.setColour(juce::TextButton::textColourOnId, juce::Colours::white);
        layermutebuttons.setColour(juce::TextButton::buttonColourId, juce::Colours::whitesmoke);
        layermutebuttons.setColour(juce::TextButton::buttonOnColourId, juce::Colours::red);
        layermutebuttons.repaint();

        layertransposetexteditors.setColour(juce::Label::textColourId, juce::Colours::white);
        layertransposetexteditors.repaint();
    }
private:
    juce::Label colourlabels;
    juce::Label layerlabels;
    juce::TextButton layersolobuttons;
    juce::TextButton layermutebuttons;
    juce::TextEditor layertransposetexteditors;

};

Editor.cpp:

DivisimateAudioProcessorEditor::DivisimateAudioProcessorEditor (DivisimateAudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);
    
    LayerComponent layer;
    layer.setText(juce::String(1), juce::String("S"), juce::String("M"), juce::String("0"));
    layer.setColor();
    layer.setBounds(10,10,50,25);
   
}

It seems you are trying to override setBounds(). If I understand what you’re trying to do…

But that’s not how it works. Take all of that function, as is, and just put it into LayerComponent::resized(), and then get rid of that.

Then, in your Editor::resized(), you need to setBounds on the LayerComponent.

resized() is where you set up the bounds of each control, by calling setBounds() for each control. resized is called automatically.

So Editor::resized() sets the bounds of the LayerComponent. Then LayerComponent::resized() sets the bounds of each control.

I hope that might help, I may not be understanding your code…

1 Like

I had updated as below shows, but still did not work. After compiling and loading in reaper, there is no any controls show on the vst3.

Editor.h:

class LayerComponent : public juce::Label
{
public:
    LayerComponent();
    ~LayerComponent();

    void paint(juce::Graphics& g) override;
    void resized() override;
    void setText(juce::String& layerLabelText, juce::String& soloButtonText, juce::String& muteButtonText, juce::String& transposeEditorText);
    void setBounds(int x, int y, int width, int height);
    void setColor();

private:
    juce::Label colourlayerlabels;
    juce::Label layertracklabels;
    juce::TextButton layersolobuttons;
    juce::TextButton layermutebuttons;
    juce::TextEditor layertransposetexteditor;
};

Editor.cpp:

DivisimateAudioProcessorEditor::DivisimateAudioProcessorEditor (DivisimateAudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);

    LayerComponent* layeromponent = new LayerComponent();
    layeromponent->setText(juce::String("1"),juce::String("S"), juce::String("M"), juce::String("0"));
    layeromponent->setBounds(10,10,50,25);
    layeromponent->resized();
    addAndMakeVisible(layeromponent);    
}


LayerComponent::LayerComponent()
{
    // 将各个组件添加到方框中
    addAndMakeVisible(colourlayerlabels);
    addAndMakeVisible(layertracklabels);
    addAndMakeVisible(layersolobuttons);
    addAndMakeVisible(layermutebuttons);
    addAndMakeVisible(layertransposetexteditor);

    // ... ... 设置各个组件的位置和大小
}

LayerComponent::~LayerComponent()
{
    // 清理资源...
    // 在析构函数中进行必要的清理工作

    // 释放动态分配的内存
    deleteAllChildren();

    // 取消订阅事件
    juce::Button::Listener* listener = dynamic_cast<juce::Button::Listener*>(this);
    if (listener != nullptr)
    {
        // 取消 Button 控件的鼠标事件订阅
        layersolobuttons.removeListener(listener);
        layermutebuttons.removeListener(listener);
        // 取消 Label 控件的鼠标事件订阅
        colourlayerlabels.removeMouseListener(this);
        layertracklabels.removeMouseListener(this);
        // 取消 TextEditor 控件的文本变化事件订阅
        layertransposetexteditor.removeListener(this);
        // 取消 Slider 控件的鼠标事件订阅
        //slider.removeTextListener
    }

    // ... ... 其他清理工作

    // 如果有需要,可以在这里释放资源或取消订阅事件等
}

void LayerComponent::paint(juce::Graphics& g)
{
    // 绘制方框的各个部分
    // ... ...
    // 获取父控件的边界
    juce::Rectangle<int> bounds = getLocalBounds();

    // 设置方形的颜色和渐变
    juce::Colour color1(0xff000000); // 黑色
    juce::Colour color2(0xffffffff); // 白色
    juce::ColourGradient gradient(color1, bounds.getTopLeft().toFloat(), color2, bounds.getBottomRight().toFloat(), false);

    // 绘制方形的背景
    g.setGradientFill(gradient);
    g.fillRoundedRectangle(bounds.toFloat(), 10.0f);

    // 绘制方形的边框
    g.setColour(juce::Colours::black);
    g.drawRoundedRectangle(bounds.toFloat(), 10.0f, 2.0f);
}
void LayerComponent::setBounds(int x, int y, int width, int height)
{
    // 在这里进行自定义的逻辑处理,例如边界检查等
    // 调用基类的 setBounds() 方法来设置控件的边界
    this->setBounds(x, y, width, height);

}
void LayerComponent::resized()
{
    // 设置各个组件的位置和大小
    // ... ...
    int x = this->getLocalBounds().getX();  // 左上角 x 坐标
    int x = this->getLocalBounds().getX();
    int y = this->getLocalBounds().getY(); // 左上角 y 坐标
    int width = this->getLocalBounds().getWidth(); // 控件宽度
    int height = this->getLocalBounds().getHeight() - 10; // 控件高度

    // 按顺序控件的width的占整个Comnent的width的比率
    int cw = 0.06; int lw = 0.1;int sbw = 0.5;int mbw = 0.1;int tew = 0.1;
    // 从第二个控件开始按顺序控件的x坐标
    int lx = x + (width * cw) + 5;
    int sbx = lx + (width * lw) + 5;
    int mbx = sbx + (width * sbw) + 5;
    int tex = mbx + (width * mbw);


    colourlayerlabels.setBounds(x, y, width * cw, height);
    layertracklabels.setBounds(lx, y, width * lw, height);
    layersolobuttons.setBounds(sbx, y, width * sbw, height);
    layermutebuttons.setBounds(mbx, y, width * mbw, height);
    layertransposetexteditor.setBounds(tex, y, width * tew, height);

    colourlayerlabels.repaint();
    layertracklabels.repaint();
    layersolobuttons.repaint();
    layermutebuttons.repaint();
    layertransposetexteditor.repaint();
}
void LayerComponent::setText(juce::String& layerLabelText, juce::String& soloButtonText, juce::String& muteButtonText, juce::String& transposeEditorText)
{
    layertracklabels.setText(layerLabelText, juce::dontSendNotification);
    layersolobuttons.setButtonText(soloButtonText);
    layermutebuttons.setButtonText(muteButtonText);
    layertransposetexteditor.setText(transposeEditorText, juce::dontSendNotification);
}

I do not understand what you are trying to do with your own setBounds() functions. Remove these functions.

Do not call layercomponent->setBounds in your Editor constructor. Do not call layercomponent->resized in your Editor constructor. resized will be called automatically.

DivisimateAudioProcessorEditor::DivisimateAudioProcessorEditor (DivisimateAudioProcessor& p)
: AudioProcessorEditor (&p), audioProcessor (p)
{
// Make sure that before the constructor has finished, you’ve set the
// editor’s size to whatever you need it to be.
setSize (400, 300);

LayerComponent* layeromponent = new LayerComponent();
layeromponent->setText(juce::String("1"),juce::String("S"), juce::String("M"), juce::String("0"));
addAndMakeVisible(layeromponent);  

In your Editor::resized(), set the bounds for the layerComponent.

DivisimateAudioProcessorEditor::resized()
{
    layercomponent->setBounds(10,10,50,25);
}

Have you followed any of the tutorials? You might benefit from a better understanding of how JUCE does things.

Also, please put three backticks (`) before each code section to properly format the code on the forum.

Even I had changed to what you said, it still don’t work.

Editor.h

class LayerComponent : public juce::Label
{
public:
    LayerComponent();
    ~LayerComponent();

    void paint(juce::Graphics& g) override;
    void resized() override;
    void setText(juce::String& layerLabelText, juce::String& soloButtonText, juce::String& muteButtonText, juce::String& transposeEditorText);
    void setColor();

private:
    juce::Label colourlayerlabels;
    juce::Label layertracklabels;
    juce::TextButton layersolobuttons;
    juce::TextButton layermutebuttons;
    juce::TextEditor layertransposetexteditor;
};

Editor.cpp

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
DivisimateAudioProcessorEditor::DivisimateAudioProcessorEditor (DivisimateAudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);
    
    LayerComponent* layeromponent = new LayerComponent();
    layeromponent->setText(juce::String("1"),juce::String("S"), juce::String("M"), juce::String("0"));
    addAndMakeVisible(layeromponent);  
}




LayerComponent::LayerComponent()
{
    // 将各个组件添加到方框中
    addAndMakeVisible(colourlayerlabels);
    addAndMakeVisible(layertracklabels);
    addAndMakeVisible(layersolobuttons);
    addAndMakeVisible(layermutebuttons);
    addAndMakeVisible(layertransposetexteditor);

    // ... ... 设置各个组件的位置和大小
}

LayerComponent::~LayerComponent()
{
    // 清理资源...
    // 在析构函数中进行必要的清理工作

    // 释放动态分配的内存
    deleteAllChildren();

    // 取消订阅事件
    juce::Button::Listener* listener = dynamic_cast<juce::Button::Listener*>(this);
    if (listener != nullptr)
    {
        // 取消 Button 控件的鼠标事件订阅
        layersolobuttons.removeListener(listener);
        layermutebuttons.removeListener(listener);
        // 取消 Label 控件的鼠标事件订阅
        colourlayerlabels.removeMouseListener(this);
        layertracklabels.removeMouseListener(this);
        // 取消 TextEditor 控件的文本变化事件订阅
        layertransposetexteditor.removeListener(this);
        // 取消 Slider 控件的鼠标事件订阅
        //slider.removeTextListener
    }

    // ... ... 其他清理工作

    // 如果有需要,可以在这里释放资源或取消订阅事件等
}

void LayerComponent::paint(juce::Graphics& g)
{
    // 绘制方框的各个部分
    // ... ...
    // 获取父控件的边界
    juce::Rectangle<int> bounds = getLocalBounds();

    // 设置方形的颜色和渐变
    juce::Colour color1(0xff000000); // 黑色
    juce::Colour color2(0xffffffff); // 白色
    juce::ColourGradient gradient(color1, bounds.getTopLeft().toFloat(), color2, bounds.getBottomRight().toFloat(), false);

    // 绘制方形的背景
    g.setGradientFill(gradient);
    g.fillRoundedRectangle(bounds.toFloat(), 10.0f);

    // 绘制方形的边框
    g.setColour(juce::Colours::black);
    g.drawRoundedRectangle(bounds.toFloat(), 10.0f, 2.0f);
}

void LayerComponent::resized()
{

    this->setBounds(10, 10, 50, 25);
    // 设置各个组件的位置和大小
    // ... ...
    int x = this->getLocalBounds().getX();  // 左上角 x 坐标
    int y = this->getLocalBounds().getY(); // 左上角 y 坐标
    int width = this->getLocalBounds().getWidth(); // 控件宽度
    int height = this->getLocalBounds().getHeight() - 10; // 控件高度

    // 按顺序控件的width的占整个Comnent的width的比率
    int cw = 0.06; int lw = 0.1;int sbw = 0.5;int mbw = 0.1;int tew = 0.1;
    // 从第二个控件开始按顺序控件的x坐标
    int lx = x + (width * cw) + 5;
    int sbx = lx + (width * lw) + 5;
    int mbx = sbx + (width * sbw) + 5;
    int tex = mbx + (width * mbw);


    colourlayerlabels.setBounds(x, y, width * cw, height);
    layertracklabels.setBounds(lx, y, width * lw, height);
    layersolobuttons.setBounds(sbx, y, width * sbw, height);
    layermutebuttons.setBounds(mbx, y, width * mbw, height);
    layertransposetexteditor.setBounds(tex, y, width * tew, height);

    colourlayerlabels.repaint();
    layertracklabels.repaint();
    layersolobuttons.repaint();
    layermutebuttons.repaint();
    layertransposetexteditor.repaint();
}
void LayerComponent::setText(juce::String& layerLabelText, juce::String& soloButtonText, juce::String& muteButtonText, juce::String& transposeEditorText)
{
    layertracklabels.setText(layerLabelText, juce::dontSendNotification);
    layersolobuttons.setButtonText(soloButtonText);
    layermutebuttons.setButtonText(muteButtonText);
    layertransposetexteditor.setText(transposeEditorText, juce::dontSendNotification);
}

OK, I’m sorry, I’ve done my best. Maybe someone else can help you.

you so kind,thank you very much .

In your constructor you call setSize (400, 300); which will call the resized() method, but in resized() you have this->setBounds(10, 10, 50, 25); which will set the component to be 50x25, rather than 400x300.

I think you probably just want to remove that line.

this->setBounds(10, 10, 50, 25);

According to JUCE document of setBounds()

if this method changes the component’s top-left position, it will make a synchronous call to moved(). If it changes the size, it will also make a call to resized().

From my point of view, calling this->setBounds() within resized() should be avoided.

// 按顺序控件的width的占整个Comnent的width的比率
int cw = 0.06; int lw = 0.1;int sbw = 0.5;int mbw = 0.1;int tew = 0.1;
// 从第二个控件开始按顺序控件的x坐标
int lx = x + (width * cw) + 5;
int sbx = lx + (width * lw) + 5;
int mbx = sbx + (width * sbw) + 5;
int tex = mbx + (width * mbw);

This block of code also looks suspicious. Although I haven’t done any calculation, assigning a float point to an integer (without explicit conversion) should be avoided in general.

colourlayerlabels.repaint();
layertracklabels.repaint();
layersolobuttons.repaint();
layermutebuttons.repaint();
layertransposetexteditor.repaint();

This block of code is uncessary. IIRC, if you set a different bound to the component, the component will be marked as dirty.

setSize (400, 300) is for main Component, this->setBounds(10, 10, 50, 25) is for my Custom class of LayerComponentcontrols

So where to put setBounds()? LayerComponent() function?

resized() is called after the component has been given a size, so you can’t specify the component’s size in resized() as it will never be called.

Typically the parent component would set the child’s bounds in its resized() method. So DivisimateAudioProcessorEditor::resized() in your case. Or you could move this->setBounds(10, 10, 50, 25); to DivisimateAudioProcessorEditor’s constructor and replace this-> with layeromponent->

but the example from Official tutorial also put the childComponent.setBounds() in resized().
https://docs.juce.com/master/tutorial_new_projucer_project.html

void resized() override
    {
        floor.setBounds (10, 297, 580, 5);
        house.setBounds (300, 70, 200, 220);
    }

It seems that you misunderstood what ImJimmi said. The tutorial says the exact same thing.

In general, if you want your plugin GUI to be resizeable, you should call the setBounds() of a component within resized() of its PARENT component.

However, if you want a fixed-size GUI, put setBounds() in its parent constructor is also correct.

1 Like

Thank you for you make me understand now, the parent component will be resized in my project. Many thanks for your kind and warm help.

btw. this is unnecessary, because you use member objects, which are automatically deleted with the class

EDIT:

Oh I see you LayerComponent, which is indeed not a class member, in this case, I would use a std::unique_ptr for that. Check the method documentation of deleteAllChildren :wink:

Okay, I’ll delete deleteAllChildren();

I thought customizing the parent class should be in Editor.h until after I learned about JUCE GUI, created the GUI project and customized it by creating a LayerComponent.h and LayerComponent.cpp of parent and child classes.

Now I have another problem with my project, would your help me? I have created a parent class LayerConponent in juce gui project that inherits from Label, and I want to set the color of the background to the object of LayerConponent in MainCongponent function, like juce gui project layer.setColour(juce::label::. backgroundColourId, juce::Colours::white) , but nothing happens! how should do to setup the background colour in MainComponent()?

LayerComponent.h

class LayerComponent  : public juce::Label
{
public:
    LayerComponent();
    ~LayerComponent() override;

    void paint (juce::Graphics&) override;
    void resized() override;
    void setLayerNumber(int Num);
    void setBGColor(juce::Colour newcolour);
private:
    //juce::Label colourlabel;
    juce::Label layerlabel;
    juce::TextButton mutebutton;
    juce::TextButton solobutton;
    juce::TextEditor transposeeditor;
    juce::ComboBox transposecombox;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LayerComponent)
};

LayerComponent.cpp

LayerComponent::LayerComponent()
{
    // In your constructor, you should add any child components, and
    // initialise any special settings that your component needs.
    //addAndMakeVisible(colourlabel);
       //ÉèÖÃLayerComponentΪ²»Í¸Ã÷

    mutebutton.setButtonText(juce::String("M"));
    solobutton.setButtonText(juce::String("S"));
    transposeeditor.setText(juce::String("0"));
    juce::StringArray stringArray = { "Minor 2nd","Major 2nd","Minor 3rd","Major 3rd","4th", "5th","Minor 6th","Major 6th","Minor 7th","Major 7th","Octave" };
    for (const auto& item : stringArray) { transposecombox.addItem(item, transposecombox.getNumItems() + 1); };

    mutebutton.setColour(juce::TextButton::textColourOffId, juce::Colours::red);
    mutebutton.setColour(juce::TextButton::textColourOnId, juce::Colours::white);
    mutebutton.setColour(juce::TextButton::buttonColourId, juce::Colours::black);
    mutebutton.setColour(juce::TextButton::buttonOnColourId, juce::Colours::red);
    mutebutton.repaint();

    solobutton.setColour(juce::TextButton::textColourOffId, juce::Colours::gold);
    solobutton.setColour(juce::TextButton::textColourOnId, juce::Colours::white);
    solobutton.setColour(juce::TextButton::buttonColourId, juce::Colours::black);
    solobutton.setColour(juce::TextButton::buttonOnColourId, juce::Colours::limegreen);
    solobutton.repaint(); 

    addAndMakeVisible(layerlabel);
    addAndMakeVisible(mutebutton);
    addAndMakeVisible(solobutton);
    addAndMakeVisible(transposeeditor);
    addAndMakeVisible(transposecombox);
}

LayerComponent::~LayerComponent()
{
}
void LayerComponent::setLayerNumber(int Num)
{
    layerlabel.setText(juce::String(Num), juce::dontSendNotification);
}
void LayerComponent::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::gold);
    g.drawRect (getLocalBounds(),1);   // draw an outline around the component

    /*g.setColour (juce::Colours::white);
    g.setFont (14.0f);
    g.drawText ("LayerComponent", getLocalBounds(),
               juce::Justification::centred, true); */  // draw some placeholder text
}

void LayerComponent::resized()
{
    // This method is where you should set the bounds of any child
    // components that your component contains..

    int x = this->getX();      
    int y = this->getY() - 11;     
    int wd = this->getWidth();  
    int ht = this->getHeight() - 5; 
    int w[6] = { 0, 25, 25, 25, 40, 100 };


    int layerx = x;                                  // w:30,h:25
    int mutex = layerx + w[1] + 3;               // w:25,h:25
    int solox = mutex + w[2] + 2;                // w:25,h:25
    int transposex = solox + w[3] + 5;           // w:30,h:25
    int transposecbx = transposex + w[4] + 5;    // w:50,h:25


    //colourlabel.setBounds(coloux, y, w * rate[1], h);
    layerlabel.setBounds(layerx, y, w[1], ht);
    mutebutton.setBounds(mutex, y, w[2], ht);
    solobutton.setBounds(solox, y, w[3], ht);
    transposeeditor.setBounds(transposex, y, w[4], ht);
    transposecombox.setBounds(transposecbx, y, w[5], ht);
}

MainComponent.cpp

MainComponent::MainComponent()
{
    setSize (1000, 700);

    layer.setOpaque(true);
    layer.setText(juce::String("WHY A WHY"), juce::dontSendNotification);
    layer.setColour(juce::Label::backgroundColourId, juce::Colours::white);
    
    layergroup.setColour(juce::Label::outlineColourId, juce::Colours::gold);
    layer.setLayerNumber(12);
    layerviewport.addChildComponent(layergroup);
    layergroup.addChildComponent(layer);

    addAndMakeVisible(layer);
    addAndMakeVisible(layergroup);
    addAndMakeVisible(layerviewport);
    
    
}

MainComponent::~MainComponent()
{
}

//==============================================================================
void MainComponent::paint (juce::Graphics& g)
{
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    g.fillAll(juce::Colours::black);
    //g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    //g.setFont (juce::Font (16.0f));
    //g.setColour (juce::Colours::white);
    //g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
}

void MainComponent::resized()
{
    // This is called when the MainComponent is resized.
    // If you add any child components, this is where you should
    // update their positions.
    layerviewport.setBounds(295,10,295,395);
    layergroup.setBounds(layerviewport.getX(), layerviewport.getY(), layerviewport.getWidth(), layerviewport.getHeight());
    layer.setBounds(5, 12, layergroup.getWidth() - 10, 30);

}

This looks like a mistake. You are deriving your class from “Label”, and then defining additional objects within that.

I learned from BingAI, it says that Label can also be used as a container for putting controls on it. and the compiled result of the program as below shows

image

A juce::Label is a juce::Component, so technically you can use it as a container. However, unless you are using the Label specialization, I don’t see why you would do this.