I have a minimal example, based on a projucer plugin, that I wrote to clarify to myself my understanding.
class DisplayBackground : public juce::Component
{
public:
DisplayBackground()
{
setOpaque (true);
}
~DisplayBackground()
{
std::cout << "DisplayBackground repainted: " << counter << std::endl;
}
void paint (juce::Graphics& g) override
{
g.setColour (juce::Colours::red);
g.fillRect (getLocalBounds());
counter++;
}
private:
long counter {0};
};
class TimedDisplay : public juce::Component,
juce::Timer
{
public:
TimedDisplay()
{
startTimer(250);
}
~TimedDisplay()
{
std::cout << "TimedDisplay repainted: " << counter << std::endl;
}
void paint (juce::Graphics& g) override
{
juce::String txt;
txt << counter;
g.drawText (txt, getLocalBounds(), juce::Justification::centred);
counter++;
}
void timerCallback() override
{
repaint();
}
private:
long counter {0};
};
class TestingOpaqueAudioProcessorEditor : public juce::AudioProcessorEditor
{
public:
TestingOpaqueAudioProcessorEditor (TestingOpaqueAudioProcessor& p)
: AudioProcessorEditor (&p), audioProcessor (p)
{
setSize (400, 300);
addAndMakeVisible (displayBackground);
addAndMakeVisible (timedDisplay);
}
~TestingOpaqueAudioProcessorEditor() override
{
std::cout << "Editor repainted: " << counter << std::endl;
}
//==============================================================================
void paint (juce::Graphics& g) override
{
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
g.setColour (juce::Colours::white);
g.setFont (juce::FontOptions (15.0f));
juce::String txt;
txt << counter;
g.drawFittedText (txt, getLocalBounds(), juce::Justification::centred, 1);
counter++;
}
void resized() override
{
displayBackground.setBounds (0, 0, 300, 30);
timedDisplay.setBounds (0, 0, 300, 30);
}
private:
// This reference is provided as a quick way for your editor to
// access the processor object that created it.
TestingOpaqueAudioProcessor& audioProcessor;
long counter {0};
DisplayBackground displayBackground;
TimedDisplay timedDisplay;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TestingOpaqueAudioProcessorEditor)
};
I would suggest running as a standalone plugin, to view the ````std::cout``` statements on exiting the application.
There are three components, the editor, DisplayBackground & TimeDisplay.
If the project is run with setOpaque(true) you will notice the counter in the TimedDisplay increasing with time, and the editor counter remains constant. When the plugin is terminated and the values of the component paint counters are displayed in the console, the editor will only be repainted a few times, while both the DisplayBackground & TimeDisplay will have been repainted the same, and many times.
if setOpaque(false) is used, when the standalone plugin is run, the display on the screen should be the same as before, with the TimedDisplay incrementing, and the editor remaining at a consistent low number. However on exit, the editors paint() has been called the same number of times as the other two child components. This is because the area of the editor behind the DisplayBackground has been rendered, so the paint() is called, even though the area containing the editors text has not been rendered.
This was tested on MacOS 14.6