# Why does my Opaque component continue to repaint when an LED it is completely covering blinks?

**URL:** <https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092>\
**Category:** General JUCE discussion\
**Created:** [January 28, 2026, 8:09pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092 "2026-01-28T20:09:01Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephenk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/stephenk/32/15198_2.png) [@stephenk](https://forum.juce.com/u/stephenk)\
**Post date:** [January 28, 2026, 8:09pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/1 "2026-01-28T20:09:01Z")

</div>

MacOS Sequoia, JUCE 8.0.10..

I have a blinking LED component that blinks according to the tempo.

I have certain floating components that can be called into existence by the user, that can completely cover the blinking LED, so that it is not visible.

And yet, when completely covered, the blinking LED continues to cause the overlapping component(s) to repaint() every time it blinks.

The overlapping component has setOpaque(true). Everything overlapping the LED has setOpaque(true).

I normally use JUCE\_COREGRAPHICS\_RENDER\_WITH\_MULTIPLE\_PAINT\_CALLS=1 but I tried recompiling with it set to 0 and no difference.

Is there a good way for the LED to tell that it is not visible at the moment, because isVisible() returns true even when it is covered up.

EDIT: I just tried isShowing() on the LED as well, and this doesn’t appear to block the repainting either.

---

<div class="post-metadata">

**Author:** ![stephenk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/stephenk/32/15198_2.png) [@stephenk](https://forum.juce.com/u/stephenk)\
**Post date:** [January 29, 2026, 2:32am UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/3 "2026-01-29T02:32:27Z")

</div>

In other words, should a component that is completely covered by another OPAQUE component continue to repaint itself, thereby propagating repaints to the component that is covering it?

---

<div class="post-metadata">

**Author:** ![PluginDev97](https://avatars.discourse-cdn.com/v4/letter/p/f05b48/32.png) [@PluginDev97](https://forum.juce.com/u/PluginDev97)\
**Post date:** [January 29, 2026, 8:44am UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/4 "2026-01-29T08:44:40Z")

</div>

when the overlaps are visible can you stop the led repaint and start it again when the overlaps disappear?

---

<div class="post-metadata">

**Author:** ![anthony-nicholls](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/anthony-nicholls/32/1246_2.png) [@anthony-nicholls](https://forum.juce.com/u/anthony-nicholls)\
**Post date:** [January 29, 2026, 12:16pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/5 "2026-01-29T12:16:06Z")

</div>

In the version of JUCE you are using not all opaque components are guaranteed to always prevent another component from drawing. There are a couple of reasons for this including where the components are in the component tree relative to each other, if a component is using `setPaintingIsUnclipped (true)`, and even if a component has children.

However, if you check out the develop branch you should see that opaque components should now _always_ prevent other components they obscure from drawing. That being said you need to weigh up the costs of drawing vs the costs of checking if an opaque component obscures another component.

In the version of JUCE you are using components always checked if they were being covered by an opaque component (with some caveats as mentioned above). This meant the price for checking for opaque components always existed so using `setOpaque()` was a no-brainer, it was unlikely to ever make performance noticeably worse.

In the latest version this cost will only be paid once a component is marked opaque, this cost is paid by all the components that need to check if they are covered by the opaque component(s). This means every component that is _potentially_\* behind an opaque component will need to perform a check to see if they have been obscured. Therefore the savings of preventing a component being drawn need to be greater than the cost of all the combined checks, otherwise setOpaque() isn’t worth it.

As a rule of thumb if the component you are hiding is inexpensive to draw don’t use `setOpaque (true)`. If it’s expensive to draw, first check you can’t implement some better/more informed logic to set the visibility of the component. If `setOpaque()` is the only option, and your UI does not consist of many components, it’s probably fine to use `setOpaque()`, otherwise _measure_ that it is actually improving performance of the _whole_ app as the cost of the checks will be paid for by potentially lots of other components. Another aspect to consider is how often the component(s) will be covered. If a component is only obscured occasionally you may still be paying for the checks on every paint call.

\*_A component is potentially behind another component if it has a lower z-order. This might be a sibling, or child of a sibling with a lower z-order, or a parent, sibling of a parent, or child of a sibling of a parent, with a lower z-order._

> [@stephenk](#):
>
> isVisible() returns true even when it is covered up.

isVisible() returns a value mirroring that of setVisible().

> [@stephenk](#):
>
> EDIT: I just tried isShowing() on the LED as well, and this doesn’t appear to block the repainting either.

`isShowing()` checks the value of `isVisible()` on this component and all it’s parents. Although a good indication of if a component is showing, actually checking _all_ the conditions required to know if a component is on screen is significantly more complicated than that and could be a potentially time consuming task if there are enough components.

---

<div class="post-metadata">

**Author:** ![stephenk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/stephenk/32/15198_2.png) [@stephenk](https://forum.juce.com/u/stephenk)\
**Post date:** [January 29, 2026, 4:07pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/6 "2026-01-29T16:07:15Z")

</div>

@anthony-nichols Thank you for the detailed response! I really appreciate it.

> [@anthony-nicholls](#):
>
> In the latest version this cost will only be paid once a component is marked opaque, this cost is paid by all the components that need to check if they are covered by the opaque component(s). This means every component that is _potentially_\* behind an opaque component will need to perform a check to see if they have been obscured. Therefore the savings of preventing a component being drawn need to be greater than the cost of all the combined checks, otherwise setOpaque() isn’t worth it.

So does this mean that the logic of “my component is completely filled with drawing; therefore, mark it opaque” will no longer be true moving forwards? Put another way: Even if your component is opaque, don’t mark it so if it’s not expensive to redraw?

I have lots of components marked `setOpaque(true)`; I guess I would need to examine all of that in the next version?

> [@anthony-nicholls](#):
>
> As a rule of thumb if the component you are hiding is inexpensive to draw don’t use `setOpaque (true)`.

Are you referring to the “under” or “over” component? In my case, the “under component” is a 10x10 pixel LED that is very cheap to draw. However, in some cases, it can be obscured by an “over component” that is very expensive to redraw when it gets repainted by the LED’s 10x10 clipRect being repainted underneath it.

> [@anthony-nicholls](#):
>
> If it’s expensive to draw, first check you can’t implement some better/more informed logic to set the visibility of the component. If `setOpaque()` is the only option, and your UI does not consist of many components, it’s probably fine to use `setOpaque()`, otherwise _measure_ that it is actually improving performance of the _whole_ app as the cost of the checks will be paid for by potentially lots of other components. Another aspect to consider is how often the component(s) will be covered. If a component is only obscured occasionally you may still be paying for the checks on every paint call.

However, having said that, the chances that this LED can be obscured by said expensive-to-paint objects is not high - so you are saying “don’t mark the expensive-to-paint object as Opaque? (Even though it is?)

“Some better more informed logic” I suppose might include the expensive-to-repaint object determining if it is covering up the LED and if so, setting the LED to isVisible(false)?

Wow, this seems like a lot of work to re-evaluate painting optimizations I thought I had already done.

---

<div class="post-metadata">

**Author:** ![anthony-nicholls](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/anthony-nicholls/32/1246_2.png) [@anthony-nicholls](https://forum.juce.com/u/anthony-nicholls)\
**Post date:** [January 29, 2026, 4:37pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/7 "2026-01-29T16:37:10Z")

</div>

> [@stephenk](#):
>
> So does this mean that the logic of “my component is completely filled with drawing; therefore, mark it opaque” will no longer be true moving forwards? Put another way: Even if your component is opaque, don’t mark it so if it’s not expensive to redraw?

Correct. Note that the performance of marking a component opaque is unlikely to be worse than it was before, but the idea is that you can potentially get better performance than before (in fact you should benefit from this better performance without doing anything).

> [@stephenk](#):
>
> Are you referring to the “under” or “over” component? In my case, the “under component” is a 10x10 pixel LED that is very cheap to draw. However, in some cases, it can be obscured by an “over component” that is very expensive to redraw when it gets repainted by the LED’s 10x10 clipRect being repainted underneath it.

Normally it’s only the “under” component that avoids being drawn, the “over” component (the opaque component) always draws (unless obscured by another opaque component).

It sounds like what you’re saying is the cheap led is being repainted often which in turn triggers the expensive component to redraw. I probably need to test that use case to give a more concrete answer.

> [@stephenk](#):
>
> so you are saying “don’t mark the expensive-to-paint object as Opaque? (Even though it is?)

Correct, although I will try to test your specific use case.

> [@stephenk](#):
>
> “Some better more informed logic” I suppose might include the expensive-to-repaint object determining if it is covering up the LED and if so, setting the LED to isVisible(false)?

Correct, if you can do that it’s going to be a lot more effective than JUCE trying to figure that out as JUCE will need to traverse lots of components to test them.

> [@stephenk](#):
>
> Wow, this seems like a lot of work to re-evaluate painting optimizations I thought I had already done.

I would not expect anyone to see a drop in performance compared to older JUCE versions, I would only expect improved performance, but it’s _possible_ your performance could be improved further by removing calls to `setOpaque (true)`.

To help with this evaluation there is some work in progress that aims to provide some drawing diagnostics you can obtain for components.

---

<div class="post-metadata">

**Author:** ![anthony-nicholls](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/anthony-nicholls/32/1246_2.png) [@anthony-nicholls](https://forum.juce.com/u/anthony-nicholls)\
**Post date:** [January 29, 2026, 4:44pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/8 "2026-01-29T16:44:16Z")

</div>

Just to add, if your expensive to draw component doesn’t change much it might be worth using `setBufferedToImage (true)` or if some aspect of it does draw regularly and another part doesn’t, you could break it into multiple components and call `setBufferedToImage (true)` on the part that doesn’t change much.

---

<div class="post-metadata">

**Author:** ![anthony-nicholls](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/anthony-nicholls/32/1246_2.png) [@anthony-nicholls](https://forum.juce.com/u/anthony-nicholls)\
**Post date:** [January 29, 2026, 4:55pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/9 "2026-01-29T16:55:27Z")

</div>

> [@stephenk](#):
>
> However, in some cases, it can be obscured by an “over component” that is very expensive to redraw when it gets repainted by the LED’s 10x10 clipRect being repainted underneath it.

OK having had a quick look JUCE does not prevent the over component from drawing if the under components repaint is triggered, unless the under component is set to invisible via `setVisible (false)`. As far as I know this has always been the case.

Implementing this for opaque checks could be an expensive traversal of components either on every call to repaint or the state would have to be cached and recalculated in a number of different situations such as when visibility, opacity, opaqueness, bounds, etc. change.

---

<div class="post-metadata">

**Author:** ![stephenk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/stephenk/32/15198_2.png) [@stephenk](https://forum.juce.com/u/stephenk)\
**Post date:** [January 29, 2026, 6:53pm UTC](https://forum.juce.com/t/why-does-my-opaque-component-continue-to-repaint-when-an-led-it-is-completely-covering-blinks/68092/10 "2026-01-29T18:53:58Z")

</div>

> [@anthony-nicholls](#):
>
> OK having had a quick look JUCE does not prevent the over component from drawing if the under components repaint is triggered, unless the under component is set to invisible via `setVisible (false)`. As far as I know this has always been the case.

I guess that was my original question. I sort of naively expected the under component to NOT repaint (and not trigger the over component) if you couldn’t actually see it.

> [@](#):
>
> Implementing this for opaque checks could be an expensive traversal of components either on every call to repaint or the state would have to be cached and recalculated in a number of different situations such as when visibility, opacity, opaqueness, bounds, etc. change.

Understood. I will attack it from the other direction (make the over component block the under component from repainting). Thank you!
