GUI App - why paint() is called multiple times once program is started

My paint() function looks like:

void MainComponent::paint (juce::Graphics& g)
    std::cout << "t: " << ++t << std::endl;

where t is a private member of MainComponent. And I noticed t is printed 90 times after the program is started. I have no clue why. It’s the CMake demo project of GUI App and I’m running it from CLion on mac os. (10.5 KB)

Because of reasons. Lol. This isn’t something people usually need to think about, why are you asking? Knowing the reason could help people in formulating answers for you.

The paint() function is called anytime the bounds of that component overlap regions of the screen flagged as “dirty” by the OS. This can happen for various reasons but is usually due to some component in the hiearchy having its repaint() method called. For example it may be due to mouse activity on the UI triggering repaints, or an animated component that’s being repainted on a timer.

…or the animated splashscreen.

1 Like

paint()/repaint() semantics are something that every new JUCE developer has to learn about, and ignore. :wink: Its not a problem that paint() is being called so many times - its going to happen for every Component that the OS (not JUCE itself) determines needs to be ‘redrawn’ due to … reasons … either a bounding rectangle was recomputed, or a UI update event was received else-wise, or some animation timer stimulated a repaint of the entire component tree … always remember that your component, even if you wrote it yourself, exists in the context of a massive ecosystem of other components. Its rectangles, all the way down, and they need to restructure the hierarchy every time a rectangle considers itself invalidated by other rectangles/events/etc.

Before people reiterate the same thing over and over, can you please elaborate where this is an actual problem?

I was following this juce tutorial where a rectangular with a random dimension is drawn at a random place within the main component. With mouseDown function implemented, the (dimension and location of ) rectangular also needs to be updated every time mouse clicked.
I did what they said in the tutorial and run the program, but every time once I see the window, the lower portion of the window flashes: I can see the rectangular is updated rapidly and then becomes static.
I suspect it was due to repeat calls to paint() function so I added the t member to check it out and found paint() was called around 90 times before it became stable. It also confused me that the upper half of the windows seems to be static while the lower half is flashing. That’s the reason why I asked about the issue.

I figured it out. It was due to the JUCE splash screen. I turned it off and UI didn’t update unexpectedly anymore. Thank everyone for the response.

Great you found a solution. Just some explanations and a bit of advice:

  • A paint call can occur at any time. Your program should be able to cope with that
  • A paint call can paint only parts of the component for performance reasons. Your program is responsible to deliver a consistent result, that is not dependant on when or how often the paint was called. This means the random rectangle is a nice toy, but unusable in a product, as it will deliver such artefacts for unforseen reasons
  • This also means paint shouldn’t alter the state of the component

If you want to create an animation, like move the rectangle, it is better to have a variable where the rectangle should be placed. Then add a Timer that calculates the rectangle position depending on the time (wall clock) and call repaint() to invalidate the view and trigger paint().

1 Like